如何释放使用C ++" new"分配的C中的内存。操作者

时间:2014-11-10 09:56:36

标签: c++ c malloc free new-operator

我使用C编写的一些函数创建自己的C / C ++库;其他用C ++编写。在库中我使用new运算符:

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

现在我在C中使用这个库:

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

当我用valgrind检查时;我得到这样的警告:

Mismatched free() / delete / delete []

但我的印象是所有内存都正确释放。我知道有两种方法可以避免这个问题。

我可以重写我的C ++代码以使用malloc:

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

我可以在我的库中编写dealloc函数:

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

我不会再有问题;但最好的方法是什么? new更容易使用;但它在valgrind中给出了那些警告。所以这里有我的问题:

  1. 如果我使用newfree,是否所有内存都已正确释放? (所以valgrind警告不是很重要)
  2. 有没有首选的方法来编程?

6 个答案:

答案 0 :(得分:9)

  1. 不保证可以正确释放,但可能,具体取决于编译器和运行时库。
  2. 总是应该以相应的方式返回内存:

      {li> free malloc
    • raw delete for raw new
    • 用户为operator delete
    • 用户定义operator new
    • 如果您的存储由某些DLL提供,请将其返回到该DLL以进行正确的解除分配
    • 如果你切开一只恐龙的腹部来收集你的存储,将记忆恢复到同一个恐龙的腹部并再用几针缝合它。
  3. 在您的情况下,编写并调用C ++库中的相应函数:

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

答案 1 :(得分:4)

除了避免混淆newfree之外,还必须确保由相同的堆管理器,相同的运行时库完成取消分配。例如,如果您newmalloc X 版本的运行时库(管理内存和堆),则不能delete或{{1使用 Y 版本的运行时库(是的,即使free匹配new)。

这就是原因,建议由DLL(Windows)进行的分配应该由同一个DLL解除分配。由于其他DLL可能具有另一个堆管理器/运行时库。还建议通过同一个线程释放内存。

答案 2 :(得分:3)

  1. 不,它没有正确释放。切勿混用malloc/freenew/delete

  2. 您已经知道解决方案了。使用malloc或编写dealloc函数。我更喜欢后者,因为它与建筑更加一致。

答案 3 :(得分:1)

从C到C ++返回指针反之亦然可能会给你带来麻烦。由于有可能混淆malloc/delete OR new/free,这会导致未定义的行为。或者你必须明确地注意它不会发生。

答案 4 :(得分:0)

1)切勿使用新的自由组合。我很难调试一个问题:(

2)最好编写一个模仿malloc和free操作的小代码。我希望你没有广泛使用内存分配

答案 5 :(得分:-1)

如果您使用new进行分配,则必须使用delete解除分配。

如果您提供分配对象的功能,则您的函数用户无需知道您的对象是否已分配newmallocmmap,{{1 }},return BIG_ARRAY + (index++)obstack_alloc或任何其他方式:您必须提供释放功能。

解除分配函数必须与分配函数配对(并使用与分配函数中使用的分配方法匹配的解除分配方法)。

这样,用户不必知道你的对象是如何分配的,如果你改变了在其他时间点分配对象的方式,它就不会破坏调用者代码。