Change in libSBML's object copying and cloning behavior
SBML objects in libSBML store pointers to both the SBMLDocument object in which the object is contained, and the direct parent of the object. In libSBML versions 1–3, copying an object copied these pointers; however this results in invalid information regarding the object and can cause issues when deleting the objects.
Example of the issue
Consider the following code:
SBMLDocument *doc = new SBMLDocument(2, 4); Model * m = doc->createModel(); Reaction * r = m->createReaction(); KineticLaw *kl = r->createKineticLaw(); // copy the reaction Reaction *r_new = new Reaction(*r); delete doc; KineticLaw *kl_new = r_new->getKineticlaw();
Here, the SBMLDocument contains a model with one reaction, and this reaction in turn contains a kinetic law object. The code above creates a copy of this reaction, and then deletes the original SBMLDocument object. At this point, the kineticLaw object from the newly created reaction (kl_new) still points to doc as its SBMLDocument and r as its parent object. Not only is this actually incorrect; but since in this example the SBMLDocument has been deleted, attempting to access the kinetic law object may cause exceptions.
In libSBML version 4, copying or assigning objects sets the internal SBMLDocument pointer to NULL, since the copy is not actually contained within the document. The internal pointer to the parent SBMLDocument is also set to NULL. However, in cases where the object being copied has child elements (e.g. a reaction containing a kineticLaw), the parentage of the child elements is reassigned to point to the true parent.