A list for the developers of CellML tools

Text archives Help


[cellml-dev] Creating component references


Chronological Thread 
  • 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.

Top of page