我正在研究一个C ++库,其函数之一返回一个(新分配的)指向双精度数组的指针。 API声明调用者有责任释放内存。
但是,该C ++库曾经在C中实现,并且所讨论的函数使用malloc()
分配内存。它还假定调用者将使用free()
释放该内存。
我是否可以通过拨打malloc()
安全地将来电替换为new
?如果我这样做,现有的客户端代码(使用free()
会破坏吗?到目前为止我能找到的是free()
的官方文档,其中说明了
如果ptr没有指向使用[malloc,calloc或realloc]分配的内存块,则会导致未定义的行为。
但我相信这是在C ++出现自己的分配运算符之前编写的。
答案 0 :(得分:17)
您必须将malloc
和free
以及new
与delete
的来电匹配。混合/匹配它们不是一种选择。
答案 1 :(得分:7)
您不能将malloc
和free
与new
和delete
混合搭配,而C ++标准草案会回溯到C99标准,如果我们去到draft C++ standard部分20.6.13
C库它说(强调我的前进):
内容与标准C库头stdlib.h相同,但有以下更改:
和
函数calloc(),malloc()和realloc()不会尝试通过调用:: operator来分配存储空间 new()(18.6)。
和
函数free()不会尝试通过调用:: operator delete()来释放存储空间。 另见:ISO C条款7.11.2。
并包含其他更改,其中没有任何更改声明我们可以对使用free
分配的内容使用new
。部分7.20.3.2
草案C99标准中的自由功能仍然是正确的参考,它说:
否则,如果参数与之前由calloc,malloc或realloc函数返回的指针不匹配,或者如果通过调用free或realloc释放空间,行为未定义
答案 2 :(得分:3)
正如你现在所听到的那样,你无法混合它们。
请记住,在C ++中,通常会动态分配大量相对较小的临时对象(例如,很容易编写像my_string + ' ' + your_string + '\n'
这样的代码),而在C内存分配中通常会更加慎重,通常会更大的平均分配大小和更长的生命周期(更有可能有人直接malloc(strlen(my_string) + strlen(your_string) + 3)
没有任何临时缓冲区的结果。因此,一些C ++库将针对大量小型瞬态对象进行优化。例如,他们可能使用malloc()
来获得三个16k块,然后分别使用每个16,5和64字节的固定大小的请求。如果在这种情况下调用delete
,它不会释放任何东西 - 它只是将16k缓冲区中的特定条目返回到C ++库免费列表。如果你调用free()
并且指针恰好是16k缓冲区中的第一个元素,那么你会意外地释放所有元素;如果它不是第一个你有未定义的行为(但一些实现,如Visual C ++显然仍然是免费块,给它们内部的任何指针)。
所以 - 真的,真的不这样做。
即使它表面上适用于您当前的系统,它也是一颗等待灭火的炸弹。不同的运行时行为(基于不同的输入,线程竞争条件等)可能导致以后的故障。使用不同的优化标志,编译器版本,操作系统等进行编译都可以随时打破它。
答案 3 :(得分:1)
库应该真正提供一个解除分配函数,转发到正确的函数。
除了其他人已经说过的内容(没有兼容性保证)之外,库也可能链接到与您的程序不同的C库,因此在从它们接收的指针上调用free()
即使函数名称正确,也会将它传递给错误的释放函数。
答案 4 :(得分:0)
当delete
运算符分配内存时,必须使用new
运算符释放内存。
答案 5 :(得分:0)
malloc()
分配内存并将第一个块的地址发送到指定的指针变量,在new的情况下,它分配内存并返回地址。这是一个约定,当你使用{{ 1}}函数我们应该使用delete函数,当你在新函数的帮助下分配内存时,malloc()
函数的使用是舒适的。当free()
这是一个约定我们应该使用相应的{ {1}}函数,类似地,当您使用malloc()
函数时,使用相应的realloc(),calloc(),delete()
函数。