1

I'm trying to call a C library in some C++ code. For simplicity let's say that the C library behaves as

utility_class data;
callback(double input[], void* data);

void* mem;
c_library_init(mem);
c_library_data(mem, &data);
c_library_callback(mem, &callback);
c_library_action(mem);
c_library_free(mem);

I then define a callback in C++ as

extern "C"
void callback(double input[], void* data) {
}

If callback is empty then the code runs fine, but if I try to allocate a standard vector,

extern "C"
void callback(double input[], void* data) {
  std::vector<double> temp(5);
}

then I get a malloc error (c_library_callback apparently calls callback at least once with no problem but errs after two or three calls),

main(33158,0x7fff75ea5310) malloc: *** error for object 0x7fe71ac0cf08:  
incorrect checksum for freed object - object was probably modified after being
freed.

Inspecting the memory with Allocations shows that objects are allocated at 0x7fe71ac0cf00 and 0x7fe71ac0cf10, but not at 0x7fe71ac0cf08 so it looks like memory corruption of some sort. I'm not even sure why free is being called in the C++ function. Moreover, this only seems to happen for some callbacks but not others.

Any suggestions on how to debug what's going on at the interface of the C and C++? Diagnostics instrumented directly in the code or through Xcode's Instruments are the most convenient, but I'll try anything. Thanks!

  • It's possible that it could be an issue with pointer ownership: you free a pointer that the library owns, or the library frees a pointer that you own (both cases lead to the same results). Could you provide us with more information on ownership for the dynamic objects in your code? More specifically: who allocates `input` and `data` , is it you or the library? And who frees these pointers, and when? – Daniel Strul Oct 26 '15 at 11:11
  • you told the compiler that the function was 'C' code, then used some C++ only code in the function, Of Course the function fails. – user3629249 Oct 26 '15 at 11:48
  • The error arises whether or not the `extern "C"` is included -- something more pathological is going on. – Michael Betancourt Oct 26 '15 at 17:27
  • Daniel -- `input` is allocated and freed by the C library while `data` is allocated and freed by the user and only passed into the C library as a pointer. It almost seems like there's a memory error in C library callback, which I'm trying to diagnose. – Michael Betancourt Oct 26 '15 at 17:29
  • From the error message, I would say the allocator is checking the content of a memory location to be allocated, and find out the location is abnormal, which means there was some sort of memory corruption (pointer used after it was freed, out-of-bounds write...) at some point in the execution of the program *before the finding is signaled*. – Daniel Strul Oct 29 '15 at 10:57
  • It is quite difficult to trace-back a memory corruption after it has occurred, so you should try enabling all memory-related runtime-checking options, to try and catch the error right when it happens. If it doesn't work, you'd probably best use some checking tool, as proposed in @Imran's answer. – Daniel Strul Oct 29 '15 at 10:58
  • 1
    Daniel, that does seem to be the case according to valgrind's diagnostics but the deeper checks are dying so it'll be a nasty process tracking this down. Thanks! – Michael Betancourt Oct 30 '15 at 11:31

2 Answers2

2

You can try valgrind on Mac. It has been very helpful for me to diagnose issues related to memory access and modification.

Here is more info to install valgrind on Mac.

Community
  • 1
  • 1
Imran
  • 413
  • 5
  • 14
1

The malloc is merely where the problem is detected, not the source of the problem. Somewhere else in your code, you write to memory that has already been freed. This can be tricky to track down, but if you inspect the memory that was written to after the free (0x7fe71ac0cf08 in your example above) to see what data was written there you may get a clue to where the problem lies. Probably somewhere between the last callback call that worked and the one that fails.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56