free()分配的新内存是否安全? [重复]

问题描述 投票:6回答:6

这个问题在这里已有答案:

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

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

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

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

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

c++ memory-management
6个回答
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释放了空间,则行为未定义。


17
投票

你必须将mallocfreenewdelete的调用相匹配。混合/匹配它们不是一种选择。


3
投票

正如你现在所听到的,你不能混合它们。

请记住,在C ++中,通常会动态分配大量相对较小的临时对象(例如,很容易编写像my_string + ' ' + your_string + '\n'这样的代码),而在C内存分配中通常会更加谨慎,通常具有更大的平均分配大小和更长的生命周期(更有可能有人直接malloc(strlen(my_string) + strlen(your_string) + 3)没有任何临时缓冲区的结果)。因此,一些C ++库将针对大量小型瞬态对象进行优化。例如,他们可能会使用malloc()来获取三个16k块,然后分别使用每个块来处理最多16,32和64字节的固定大小的请求。如果你在这种情况下调用delete,它不会释放任何东西 - 它只是将16k缓冲区中的特定条目返回到C ++库免费列表。如果你调用free()并且指针碰巧是16k缓冲区中的第一个元素,那么你会意外地释放所有元素;如果它不是第一个你有未定义的行为(但一些实现,如Visual C ++显然仍然是免费块,给它们内部的任何指针)。

所以 - 真的,真的不这样做。

即使它表面上适用于您当前的系统,它也是一颗等待灭火的炸弹。不同的运行时行为(基于不同的输入,线程竞争条件等)可能导致以后的故障。使用不同的优化标志,编译器版本,操作系统等编译可以随时打破它。


1
投票

该库应该真正提供一个解除分配功能,转发到正确的功能。

除了其他人已经说过的内容(没有兼容性保证)之外,还有可能将库链接到与程序不同的C库,因此在从它们接收的指针上调用free()会将其传递给错误的释放即使函数名称正确也可以运行。


0
投票

delete运算符分配内存时,必须使用new运算符释放内存。


0
投票

malloc()分配内存并将第一个块的地址发送到指定的指针变量,在新的情况下,它分配内存并返回地址。这是一个约定,当你使用malloc()函数时,我们应该使用delete函数,当你在新函数的帮助下分配内存free()函数的使用是舒适的。当malloc()it是一个惯例,我们应该使用相应的realloc(),calloc(),delete()函数,类似地,当你使用new()函数时,使用相应的free()function。

© www.soinside.com 2019 - 2024. All rights reserved.