how to free memory in C that was allocated using C++ "new" operator

2.6k Views Asked by At

I make my own C/C++ libraries with some functions written in C; other in C++. Inside the library I use the new operator:

mystruct * mystruct_alloc()
    {
    mystruct * ms = new mystruct;
    return ms;
    }

Now I use this library in C like this:

mystruct *ms = mystruct_alloc();
// do stuff
free(ms);

When I check this with valgrind; I get warnings like this:

Mismatched free() / delete / delete []

But I have the impression that all memory is freed correctly. I know that there are two ways to circumvent this problem.

I could rewrite my C++ code to use malloc:

mystruct * mystruct_alloc()
    {
    mystruct * ms = (mystruct *) malloc (sizeof(mystruct));
    return ms;
    }

I could write a dealloc function in my library:

void mystruct_dealloc(mystruct *ms)
    {
    delete ms;
    }

and I would have no more problems; but what is the best way? new is easier to use; but it gives those warnings in valgrind. So here are my questions:

  1. Is all memory freed correctly if I use new and free? (so the valgrind warning is not very important)
  2. Is there a preferred way to program this?
6

There are 6 best solutions below

1
On BEST ANSWER
  1. It is not guaranteed to be freed correctly, but it might, depending on the compiler and runtime library.
  2. You always should return memory in the corresponding way to how you got it:

    • free for malloc
    • raw delete for raw new
    • a user defined operator delete for a user defined operator new
    • if your storage was provided by some DLL, return it to that DLL for proper deallocation
    • if you cut open a dinosaur's belly to get your storage, return the memory into the same dinosaur's belly and close it again with a few stitches.

In your case, write and call a corresponding function in your C++ library:

void mystruct_free(mystruct* ms)
{
  delete ms;
}
0
On

Returning pointers from C to C++ and vice-versa could create problems for you. Since there would be a chance to mix up malloc/delete OR new/free which would result in an un-defined behavior. OR you have to take care of that explicitly that it doesn't happen.

0
On
  1. No it's not freed correctly. Never mix malloc/free and new/delete.

  2. You already know the solution. Either use malloc, or write dealloc function. I would prefer the latter as it would be more consistent with the construction.

2
On

If you allocate with new, you must deallocate with delete.

If you provide a function to allocate your object, the user of your function does not need to know if your object is allocated with new, malloc, mmap, return BIG_ARRAY + (index++), obstack_alloc, my_custom_allocator.allocate(sizeof(mystruct)) or any other way: you have to give a deallocation function.

The deallocation function must be paired with the allocation function (and use the deallocation method matching the allocation method used in the allocation function).

This way, the user does not have to know how your object has been allocated and if you change the way you allocate your object at some other point in time, it won't break the caller code.

0
On

Other than just avoiding the mixed up new with free, you must also ensure that de-allocation is being done by same heap-manager, same runtime library. For example, if you new or malloc, with X version of a runtime library (which manages memory and heap), you cannot delete or free using Y version of runtime library (Yes, even if new is matching delete).

That's the reason, it is recommended that allocation made by a DLL (Windows), should be de-allocated by same DLL. Since other DLL may have another heap-manager/runtime-library. It is also advised to free memory by same thread.

0
On

1) Never use new and free combination . I have tough time debugging one issue :(

2)Better write a small code which mimics the malloc and free operation. I hope you are not using memory allocation extensively