我正在处理一个C++库,其中一个函数返回一个指向双重数组的(新分配的)指针。API声明调用方有责任释放内存。
但是,这个C++库以前是用C实现的,而这个函数用malloc()分配内存。它还假定调用方将使用free()释放该内存。
我能否安全地将对malloc()的调用替换为对new的调用?如果我这样做,现有的客户端代码(使用free()的代码)会中断吗?到目前为止,我所能找到的只有free()的正式文档,其中指出
如果ptr没有指向使用malloc、calloc或realloc分配的内存块,则会导致未定义的行为。
但我相信这是在C++和它自己的分配运营者出现之前写的。
发布于 2014-03-14 13:36:06
您不允许将malloc和free与new和delete混合和匹配,C++标准草案为此引用了C99标准,如果我们访问起草C++标准节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函数先前返回的指针不匹配,或者如果空间已通过调用空闲或realloc而被释放,则为,则行为为未定义的。
发布于 2014-03-14 13:27:14
必须将对malloc的调用与free匹配,new与delete匹配。混合/匹配它们不是一种选择。
发布于 2014-03-14 13:50:23
就像你现在听到的,你不能把它们混合在一起。
请记住,在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缓冲区中的第一个元素,则会意外地释放所有元素;如果不是第一个元素,则会有未定义的行为(但某些实现(例如VisualC++)显然仍然释放给定指针的块)。
所以-真的,真的不要这么做。
即使它表面上在你现在的系统上有效,它也是一颗等待爆炸的炸弹。不同的运行时行为(基于不同的输入、线程竞争条件等)可能会导致以后的失败。使用不同的优化标志、编译器版本、OS等编译都可以在任何时候破坏它。
https://stackoverflow.com/questions/22406278
复制相似问题