- From: ak.miller at auckland.ac.nz (Andrew Miller)
- Subject: [cellml-dev] Creating component references
- Date: Wed, 12 Jan 2011 08:20:45 +1300
On 06/01/11 10:37, Lucian Smith wrote:
>
Yet another question....
>
>
So, I have the recursive function:
>
>
iface::cellml_api::ComponentRef*
>
Module::GetComponentRef(iface::cellml_api::Model* model, std::string
>
cmlname, Module* topmod)
>
{
>
RETURN_INTO_OBJREF(cr, iface::cellml_api::ComponentRef,
>
model->createComponentRef());
>
cr->componentName(makeUTF16(cmlname).c_str());
>
for (size_t var=0; var<m_variables.size(); var++) {
>
if (m_variables[var]->GetType() == varModule) {
>
string subvarcmlname =
>
topmod->GetCellMLNameOf(m_variables[var]->GetName());
>
iface::cellml_api::ComponentRef* subcr =
>
m_variables[var]->GetModule()->GetComponentRef(model, subvarcmlname,
>
topmod);
>
cr->addElement(subcr);
>
}
>
}
>
return cr;
>
}
>
>
(in module-cellml.cpp), which is supposed to set up the encapsulation tree
>
in CellML that mimics the submodel tree in Antimony. However, it crashes
>
at 'cr->addElement(subcr)', and valgrind complains that the previous line
>
had an invalid read 'of size 4'. My best guess is that when I create 'cr'
>
in one function, I'm not properly adding a reference to it before
>
returning it, so it gets destroyed before I get a chance to add it to
>
anything. Am I right, and if so, how do I fix that?
Hi Lucian,
I'd suggest having a consistent rule for who has to free memory / call
release_ref. In the CellML API (and for all API functions), the rules
are in
cellml-api/simple_interface_generators/docs/MemoryManagement.txt - but
basically, API functions that return something that needs to be released
or destroyed where required, and the caller has the responsibility to
release or destroy them. RETURN_INTO_OBJREF and RETURN_INTO_WSTRING
simplify two cases of this for the caller, by ensuring that everything
is released or deleted when the variable goes out of scope.
In your Module::GetComponentRef, cr goes into an ObjRef with
RETURN_INTO_OBJREF, and so gets released at the end of the function, but
you return cr. Calling cr->add_ref() before return will prevent the
release - but then you need to ensure all callers to
Module::GetComponentRef release the returned ComponentRef - perhaps
using RETURN_INTO_OBJREF. AddEncapsulationTo already does that - but the
recursive call would need to be changed to use RETURN_INTO_OBJREF or
explicitly call release_ref() or it would leak.
Best wishes,
Andrew
>
>
(if you want to try this for yourself, try
>
'antimony2cellml doc/examples/ex_antimony_input.txt' from the latest SVN.)
>
>
I do apologize for peppering you with question like this! I hope I'm
>
almost done; many things now work great, and I think I'm closing in on the
>
edges that still don't quite work.
>
>
-Lucian
- [cellml-dev] Creating component references, Andrew Miller, 01/12/2011
Archive powered by MHonArc 2.6.18.