Now the simulation runs fine, but it is not finishing nicely.
In the C, there are many commands freeing the memory:
void fmi2FreeInstance(fmi2Component c) {
ModelInstance *comp = (ModelInstance *)c;
if (!comp) return;
if (invalidState(comp, "fmi2FreeInstance", MASK_fmi2FreeInstance))
return;
FILTERED_LOG(comp, fmi2OK, LOG_FMI_CALL, "fmi2FreeInstance")
if (comp->r) comp->functions->freeMemory(comp->r);
if (comp->i) comp->functions->freeMemory(comp->i);
if (comp->b) comp->functions->freeMemory(comp->b);
if (comp->s) {
int i;
for (i = 0; i < NUMBER_OF_STRINGS; i++){
if (comp->s[i]) comp->functions->freeMemory((void *)comp->s[i]);
}
comp->functions->freeMemory((void *)comp->s);
}
if (comp->isPositive) comp->functions->freeMemory(comp->isPositive);
if (comp->instanceName) comp->functions->freeMemory((void *)comp->instanceName);
if (comp->GUID) comp->functions->freeMemory((void *)comp->GUID);
comp->functions->freeMemory(comp);
}
Given that I keep ModelInstance as a Nim object and I am passing ModelInstanceRef (a ref object) across all functions fmi2xxx functions, how should I clean the memory properly?
I tried the following:
1. Assigning nil:
proc fmi2FreeInstance(comp: ModelInstanceRef) =
echo "ENTERING: fmi2FreeInstance"
comp = nil
but it fails to compile:Error: 'comp' cannot be assigned to.
2. If I do:
proc fmi2FreeInstance(comp: var ModelInstanceRef) =
echo "ENTERING: fmi2FreeInstance"
comp = nil
it compiles and runs fine, but it finish with a seg fault:
[INFO][FMUCHK] Simulation finished successfully at time 1
ENTERING: fmi2FreeInstance
munmap_chunk(): invalid pointer
./build.sh: line 8: 694837 Segmentation fault (core dumped) ./fmuCheck.linux64 inc.fmu
How should I remove the reference to the object?
Should I also implement =destroy for the ModelInstance object?
Well, I fixed it with:
proc fmi2FreeInstance*(comp: ModelInstanceRef) =
`=destroy`(comp[])
GC_fullCollect()
I hope this helps others.
Valgrind says:
==716751==
==716751== HEAP SUMMARY:
==716751== in use at exit: 0 bytes in 0 blocks
==716751== total heap usage: 243 allocs, 243 frees, 459,502 bytes allocated
==716751==
==716751== All heap blocks were freed -- no leaks are possible
==716751==
==716751== For lists of detected and suppressed errors, rerun with: -s
==716751== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
So this looks good.