0

I am testing a little sound library called clunk (http://sourceforge.net/projects/clunk/). I built that library for visual studio 11 and linked it in my visual studio project. When I try the test.cpp I am getting an assertion thrown by msvcr110d.dll.

Does it have to do with my runtime librarie settings: It is "Multithreaded-Debug-DLL (/MDd)" ? In cmakelist.txt in clunk I added following line of code:

set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd")

I am still getting the message that there are problems with pointer allocation. Why that?

iSteffi
  • 178
  • 2
  • 11
  • 1
    ***"I am getting an assertion thrown by msvcr110d.dll"*** - be more specific please – LihO Feb 15 '13 at 11:28
  • To start with, run your program in the debugger to pinpoint where in your code the error happens. Then you can make an [SSCCE](http://sscce.org/) to show us what you do. – Some programmer dude Feb 15 '13 at 11:29
  • What actually happens: 1. in test.cpp: load sample: _s->load("scissors.wav");_ 2. in sample::load: a buffer (_clunk::Buffer wav;_) is passed to the context (_context->convert(data, wav, spec.freq, spec.format, spec.channels);_) 3. after method reached end: buffer::free is called (in destructor) – iSteffi Feb 15 '13 at 12:22
  • 4. in clunk.dll!_free_dbg_nolock(void * pUserData, int nBlockUse) -> (__ASSERTE(_CrtIsValidHeapPointer(pUserData));_) – iSteffi Feb 15 '13 at 12:23
  • **That is what happens** – iSteffi Feb 15 '13 at 12:24

1 Answers1

7

You're probably allocating memory on one side of an application/library boundary and freeing it on the other. That's difficult to get right and likely best avoided.

You must ensure that memory is returned to the very same allocator that allocated it. Here are a few patterns to avoid this problem:

  1. Instead of the library allocating memory for a returned structure, have the application do it. Then the application can free the structure.

  2. Let the library allocate memory for a structure, but instead of the application freeing it, have the application call a special free function. So if there's a 'getFoo' function in the library that returns an allocated structure, have a 'freeFoo' function that releases that structure. This ensures the library returns the structure to its own allocator.

  3. Have the library use statically allocated structures that are valid until some particular next call into the library.

  4. Give the library a 'setAlloctor' function and pass it a pointer to malloc and free from the application. This way, the library will always use the application's allocator.

  5. Give the library a getAllocator function that returns pointers to the malloc and free functions the library is using. This way, the application can get memory from the library's allocator (for the library to possibly free) or return memory to the library's allocator (that the library allocated).

Take a look at the code that's generating the assertion and see if it can be modified to use one of these patterns. It's possible, for example, that you're just calling delete on a pointer to an object you got from the library when you should be using a special destructor function provided by the library.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • 1
    These are all excellent suggestions but rely on you either controlling both libraries or being willing and able to make large changes to both. In this question, iSteffi appears to be using an open source library. It wouldn't be surprising if (s)he didn't want to make disruptive changes to this externally maintained code. – simonc Feb 15 '13 at 11:51
  • Right, but what if it only requires trivial changes like calling the library's `freeFoo` function instead of `delete`? Or calling the library's allocation function instead of `malloc` or `new`? – David Schwartz Feb 15 '13 at 11:53
  • Good point. Is your answer meant to read as *"Here are some examples of good practice. Check to see whether any are available to you with clunk."*? I didn't read it that way; it might be possible to reword a little to clarify. – simonc Feb 15 '13 at 11:56
  • I thought it was obvious that when someone gives suggestions you see which ones might apply to solving your problem. But I updated the answer in case it wasn't. – David Schwartz Feb 15 '13 at 11:58
  • Thanks. I've encountered a few libraries which don't offer any of your suggestions so had initially thought you were advising changing clunk if necessary. +1 and no more pedantic requests now – simonc Feb 15 '13 at 12:02
  • I am not sure if these suggestions would help in this case? I did not change anything in the library not even test.cpp. I just wanted to test it. I am assuming that it should do without changes ?! – iSteffi Feb 15 '13 at 12:38
  • Did you look at the code that's generating the exception? What does it do? – David Schwartz Feb 15 '13 at 12:47
  • have a look at my comment above: What actually happens: 1. in test.cpp: load sample: s->load("scissors.wav"); 2. in sample::load: a buffer (clunk::Buffer wav;) is passed to the context (context->convert(data, wav, spec.freq, spec.format, spec.channels);) 3. after method reached end: buffer::free is called (in destructor) 4. in clunk.dll!_free_dbg_nolock(void * pUserData, int nBlockUse) -> (_ASSERTE(_CrtIsValidHeapPointer(pUserData));) – iSteffi Feb 15 '13 at 12:49
  • FWIW, the clunk buffer code looks appears to enforce allocation/freeing of memory on different sides of the library boundary. Various `Buffer` functions call `realloc` for memory which is freed by an inline dtor – simonc Feb 15 '13 at 13:12
  • If there's no way to work around it, and there usually is but maybe not in this case, then you have to somehow make sure both the library and the application are using the same allocator. That can be quite a challenge. – David Schwartz Feb 15 '13 at 13:14