我用C C++编写了一些函数,用C++编写了一些函数,其他函数是用编写的。在库内,我使用 new
运算符:
mystruct * mystruct_alloc()
{
mystruct * ms = new mystruct;
return ms;
}
现在我在 C 中使用这个库是这样的:
mystruct *ms = mystruct_alloc();
// do stuff
free(ms);
当我与瓦尔格林德检查这一点时;我收到这样的警告:
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
更易于使用;但它在瓦尔格林德给出了这些警告。所以这是我的问题:
- 如果我使用
new
和free
,是否正确释放了所有内存?(所以瓦尔格林德警告不是很重要( - 有没有首选的编程方法?
- 不能保证正确释放它,但可能会,具体取决于编译器和运行时库。 您
始终应该以相应的方式将内存返回到您获得它的方式:
-
free
malloc
- 用于原始
new
的原始delete
- 用户定义
operator new
的用户定义operator delete
- 如果存储由某个 DLL 提供,请将其返回到该 DLL 以进行适当的释放
- 如果你切开一只恐龙的肚子来获取你的存储空间,把记忆放回同一只恐龙的肚子里,然后缝几针再次关闭它。
-
在您的情况下,在C++库中编写并调用相应的函数:
void mystruct_free(mystruct* ms)
{
delete ms;
}
除了避免与free
混淆new
之外,您还必须确保取消分配是由相同的堆管理器,相同的运行时库完成的。例如,如果使用 X 版本的运行时库(管理内存和堆(new
或malloc
,则无法使用 Y 版本的运行时库delete
或free
(是,即使new
匹配delete
(。
这就是原因,建议由DLL(Windows(进行的分配应由同一DLL取消分配。由于其他DLL可能有另一个堆管理器/运行时库。还建议通过同一线程释放内存。
-
不,它没有正确释放。切勿将
malloc/free
和new/delete
混为一谈。 -
您已经知道解决方案。要么使用
malloc
,要么编写dealloc
函数。我更喜欢后者,因为它与结构更一致。
从 C 返回指向 C++的指针,反之亦然可能会给您带来问题。因为有可能混淆malloc/delete
或new/free
这会导致未定义的行为。或者你必须明确地注意它不会发生。
1(切勿使用新的和自由的组合。我很难调试一个问题:(
2(最好写一个小代码来模仿malloc和自由操作。我希望你没有广泛使用内存分配
如果使用 new
进行分配,则必须使用 delete
进行分配。
如果你提供了一个函数来分配你的对象,你的函数的用户不需要知道你的对象是用new
、malloc
、mmap
、return BIG_ARRAY + (index++)
、obstack_alloc
、my_custom_allocator.allocate(sizeof(mystruct))
还是任何其他方式分配的:你必须给出一个释放函数。
必须与分配函数配对(并使用与分配函数中使用的分配方法匹配的解除分配方法(。
这样,用户就不必知道对象是如何分配的,如果您在其他时间点更改分配对象的方式,它不会破坏调用方代码。