free()分配的新内存是否安全?

时间:2014-03-14 13:24:28

标签: c++ memory-management

我正在研究一个C ++库,其函数之一返回一个(新分配的)指向双精度数组的指针。 API声明调用者有责任释放内存。

但是,该C ++库曾经在C中实现,并且所讨论的函数使用malloc()分配内存。它还假定调用者将使用free()释放该内存。

我是否可以通过拨打malloc()安全地将来电替换为new?如果我这样做,现有的客户端代码(使用free()会破坏吗?到目前为止我能找到的是free()的官方文档,其中说明了

  

如果ptr没有指向使用[malloc,calloc或realloc]分配的内存块,则会导致未定义的行为。

但我相信这是在C ++出现自己的分配运算符之前编写的。

6 个答案:

答案 0 :(得分:17)

您必须将mallocfree以及newdelete的来电匹配。混合/匹配它们不是一种选择。

答案 1 :(得分:7)

您不能将mallocfreenewdelete混合搭配,而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()函数。