The Generic Object System makes use of reference counting to know when to delete an object. The rule is that any object that is created with the S_NEW and S_NEW_FROM_NAME related macros must be deleted with a call to S_DELETE. There are a few exceptions to this rule:
Containers - when a created object is added to a container, the container takes hold of the object, and the object should not be deleted. For example:
SList *list = NULL; SObject *a = NULL; /* Create a new list */ list = S_LIST(S_NEW(SListList, error)); /* Create some object and put the into the list */ a = SObjectSetInt(10, error); SListPush(list, a, error);The call to SListPush() adds the created object to the list, and the list is now responsible for the memory of the object. When the list is deleted with S_DELETE, then it will delete the object.
Iterators - Container iterators are created with calls to either SContainerGetIterator() or S_ITERATOR_GET(). Iterators need not be deleted with S_DELETE, except if the iteration over the container (SIteratorNext()) did not reach the end of the container. For example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 SIterator *itr = NULL; int counter = 0; int loop_fin = 1; itr = S_ITERATOR_GET(list, error); /* iterate through list objects and print them to stdout */ for (/* NOP */; itr != NULL; itr = SIteratorNext(itr)) { char *buf; const SObject *tmp; tmp = SIteratorObject(itr, error); buf = SObjectPrint(tmp, error); printf("list object = %s\n", buf); S_FREE(buf); counter++; if (counter == 2) { loop_fin = 0; break; } } if (!loop_fin) S_DELETE(itr, "main", error);In this example the iteration over the container is stopped if the container has more than 2 objects. Therefore the itr object still has memory associated with it and must be deleted.
Heterogeneous Relation Graphs - Items are created by either adding them as daughters of already existing items, or appending them to already existing relations. Relations are created by adding them to already existing utterances. The items and relations make up the HRG structure, and a call to the S_DELETE macro on these objects will not delete them. A relation can be deleted with a call to SUtteranceDelRelation(), which will delete all of the relation’s items.
The const-correctness principles are followed as far as possible. When a function’s argument has a const keyword, then the function will treat the argument as immutable. When a function’s return type has a const keyword, then the caller must treat the returned object as immutable. This is of course a compile-time construct that indicates what a programmer should do, not necessarily what they can do.