memory leaks from KIM_API_model_info/KIM_API_get_num_free_params

Hi,

I am currently polishing the openKIM integration in potfit, which has been
contributed by Mingjian Wen. However, for certain routines I get memory leaks,
which I don’t know how to fix.

Basically I just want to query some model parameters and not initialize
or setup any calculation. Here is some pseudo-code:

void consume_memory()
{
void* pkim = NULL;
KIM_API_model_info(&pkim, model_name);

int descriptor_str_len = 0;
KIM_API_get_model_kim_str_len(model_name, &descriptor_str_len);

char * descriptor_str = NULL;
KIM_API_get_model_kim_str(model_name, &descriptor_str);

int numfreeparams = 0;
int maxstringlength = 0;
KIM_API_get_num_free_params(pkim, &numfreeparams, &maxstringlength);

// do some stuff with the descriptor string here

free(descriptor_str);
}

After calling this method there is about 50k memory which is not released:

==32522==ERROR: LeakSanitizer: detected memory leaks

Indirect leak of 33784 byte(s) in 1 object(s) allocated from:
#0 0x7f5e79c85622 in operator new[](unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libasan.so.2+0x99622)
#1 0x7f5e7999d230 in KIM_API_model::prestring_init(char const*) /home/daniel/workspace/potfit_openkim/kim-api-v1.7.3/src/KIM_API.cpp:825

Indirect leak of 5096 byte(s) in 1 object(s) allocated from:
#0 0x7f5e79c85622 in operator new[](unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libasan.so.2+0x99622)
#1 0x7f5e799a4359 in KIM_API_model_info /home/daniel/workspace/potfit_openkim/kim-api-v1.7.3/src/KIM_API_C.cpp:124

Indirect leak of 4992 byte(s) in 39 object(s) allocated from:
#0 0x7f5e79c854a2 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libasan.so.2+0x994a2)
#1 0x7f5e799849ae in KIMBaseElement::init(char const*, char const*, long, long, int*, void*) /home/daniel/workspace/potfit_openkim/kim-api-v1.7.3/src/KIM_API.cpp:451

Indirect leak of 4992 byte(s) in 39 object(s) allocated from:
#0 0x7f5e79c85622 in operator new[](unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libasan.so.2+0x99622)
#1 0x7f5e79984a12 in KIMBaseElement::init(char const*, char const*, long, long, int*, void*) /home/daniel/workspace/potfit_openkim/kim-api-v1.7.3/src/KIM_API.cpp:454

Indirect leak of 3040 byte(s) in 38 object(s) allocated from:
#0 0x7f5e79c854a2 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libasan.so.2+0x994a2)
#1 0x7f5e7999cf04 in KIM_API_model::prestring_init(char const*) /home/daniel/workspace/potfit_openkim/kim-api-v1.7.3/src/KIM_API.cpp:796

Indirect leak of 624 byte(s) in 39 object(s) allocated from:
#0 0x7f5e79c854a2 in operator new(unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libasan.so.2+0x994a2)
#1 0x7f5e7998497b in KIMBaseElement::init(char const*, char const*, long, long, int*, void*) /home/daniel/workspace/potfit_openkim/kim-api-v1.7.3/src/KIM_API.cpp:449

Indirect leak of 547 byte(s) in 39 object(s) allocated from:
#0 0x7f5e79c85622 in operator new[](unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libasan.so.2+0x99622)
#1 0x7f5e799849e6 in KIMBaseElement::init(char const*, char const*, long, long, int*, void*) /home/daniel/workspace/potfit_openkim/kim-api-v1.7.3/src/KIM_API.cpp:452

Indirect leak of 328 byte(s) in 1 object(s) allocated from:
#0 0x7f5e79c85622 in operator new[](unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libasan.so.2+0x99622)
#1 0x7f5e79985b05 in KIMBaseElement::init(char const*, char const*, long, long, int*) /home/daniel/workspace/potfit_openkim/kim-api-v1.7.3/src/KIM_API.cpp:498

Indirect leak of 192 byte(s) in 7 object(s) allocated from:
#0 0x7f5e79c85622 in operator new[](unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libasan.so.2+0x99622)
#1 0x7f5e79987d1f in KIM_API_model::KIM_API_model() /home/daniel/workspace/potfit_openkim/kim-api-v1.7.3/src/KIM_API.cpp:703

Indirect leak of 136 byte(s) in 1 object(s) allocated from:
#0 0x7f5e79c85622 in operator new[](unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libasan.so.2+0x99622)
#1 0x7f5e7998efc4 in KIM_API_model::init_AtomsTypes() /home/daniel/workspace/potfit_openkim/kim-api-v1.7.3/src/KIM_API.cpp:2678

Indirect leak of 56 byte(s) in 1 object(s) allocated from:
#0 0x7f5e79c85622 in operator new[](unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libasan.so.2+0x99622)
#1 0x7f5e799879bf in KIM_API_model::KIM_API_model() /home/daniel/workspace/potfit_openkim/kim-api-v1.7.3/src/KIM_API.cpp:693

Indirect leak of 56 byte(s) in 1 object(s) allocated from:
#0 0x7f5e79c85622 in operator new[](unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libasan.so.2+0x99622)
#1 0x7f5e79987950 in KIM_API_model::KIM_API_model() /home/daniel/workspace/potfit_openkim/kim-api-v1.7.3/src/KIM_API.cpp:692

Indirect leak of 28 byte(s) in 1 object(s) allocated from:
#0 0x7f5e79c85622 in operator new[](unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libasan.so.2+0x99622)
#1 0x7f5e799878e1 in KIM_API_model::KIM_API_model() /home/daniel/workspace/potfit_openkim/kim-api-v1.7.3/src/KIM_API.cpp:691

Indirect leak of 16 byte(s) in 2 object(s) allocated from:
#0 0x7f5e79c85622 in operator new[](unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libasan.so.2+0x99622)
#1 0x7f5e79984ad5 in KIMBaseElement::init(char const*, char const*, long, long, int*, void*) /home/daniel/workspace/potfit_openkim/kim-api-v1.7.3/src/KIM_API.cpp:475

Indirect leak of 16 byte(s) in 4 object(s) allocated from:
#0 0x7f5e79c85622 in operator new[](unsigned long) (/usr/lib/gcc/x86_64-pc-linux-gnu/5.4.0/libasan.so.2+0x99622)
#1 0x7f5e79984ca9 in KIMBaseElement::init(char const*, char const*, long, long, int*, void*) /home/daniel/workspace/potfit_openkim/kim-api-v1.7.3/src/KIM_API.cpp:466

SUMMARY: AddressSanitizer: 53903 byte(s) leaked in 214 allocation(s).

I cannot find any API method which would clean up this memory.
KIM_API_model_destroy and KIM_API_free both result in a segmentation fault
because they probably should not be called here.

Is there any way to release this memory?
I guess I could not call KIM_API_model_info and KIM_API_get_num_free_params
and then calculate numfreeparams and maxstringlength myself.

Thanks,
Daniel

Hi,

I guess I solved my issue by calling KIM_API_free().
However, in my opinion the API documentation is a little misleading.
It says:

void KIM_API_free(void *kimmdl, int *kimerror);

But passing my plain void* will cause a segfault. Reading the
additional sentence (in C++ style, the definition will be (KIM_API_model **))
clarifies this a little, but still makes it difficult to understand.

So in the end my IDE shows void* (from the definition in the header file)
and I have to pass void**.
But for some other functions which require a void* I actually
have to pass void*. You probably wanted to avoid passing void**.

Sorry for the confusion.

Best regards,
Daniel

Hi Daniel,

Thanks for your messages and sorry for the confusion caused by the documentation. I agree with your assessment. We were not careful enough when we initial designed and implemented some of the api functions and this has led to a number of inconsistencies and non-idiomatic definitions/behavior in the kim-api.

This is a good prompt for me to evaluate these issues and see how much of this can cleanly be fixed/improved in the forthcoming kim-api-v2.0.0.

I'm glad you got your code working. As always, we're happy to see inquiries, of any type, on this list! Don't hesitate to post questions/comments/etc. as they arise.

Cheers and Happy 2017!