我知道free()
不会调用析构函数,但是除了成员变量无法正确销毁之外,这还会引起什么问题吗?
另外,如果我们删除使用malloc
分配的指针会发生什么?
我知道free()
不会调用析构函数,但是除了成员变量无法正确销毁之外,这还会引起什么问题吗?
另外,如果我们删除使用malloc
分配的指针会发生什么?
实现定义了new
是否在幕后使用malloc
。如果混合使用new
和free
,以及malloc
和delete
可能会在运行时导致灾难性故障,如果代码被移植到新的机器、新的编译器,甚至是同一编译器的新版本。
我知道free()不会调用析构函数
这已经足够的理由不去使用它。
此外,C++实现没有要求使用相同的内存区域来进行malloc
和new
操作,所以你可能试图释放来自完全不同区域的内存,这几乎肯定会导致致命错误。
需要注意的几点:
delete
调用析构函数,而 free
不会... 您可能有一些 POD 类型并且不在意,但其他人可能会添加一个字符串到该类型中,而没有意识到其内容存在奇怪的限制。malloc
并忘记使用放置 new
来构建其中的对象,然后调用成员函数,就好像该对象已存在(包括 delete
调用析构函数),则成员函数可能会尝试使用带有垃圾值的指针进行操作。new
和 malloc
可能从不同的堆中获取内存。malloc
来获取其内存,也可能不存在 new
/delete
与底层 malloc
/free
行为之间的一对一对应关系。
new
可能具有额外的逻辑,例如对典型 C++ 程序有益但对典型 C 程序有害的小对象优化。new
,或链接调试版本的 malloc
/realloc
/free
,其中任何一种都可能在您未正确使用这些函数时出现故障。delete[]
调用所有析构函数,而 free()
不会,但是堆内存通常具有数组大小的计数器(例如,对于 32 位 VC++2005 发行版,数组大小在指针值明显返回的 4 字节之前)。 对于 POD 类型,可能不存在此额外值(对于 VC++2005 并非如此),但如果存在,则 free()
肯定不会期望它。 并非所有堆实现都允许您释放已从 malloc()
返回的值移动的指针。一个重要的区别是,new和delete还会调用对象的构造函数和析构函数。因此,可能会出现意外的行为。我认为这是最重要的事情。
因为可能不是同一个分配器,这可能导致奇怪、难以预测的行为。此外,您根本不应该使用malloc/free,并避免在不必要的情况下使用new/delete。
这完全取决于实现方式 - 可以编写一个实现,使其正常工作。但是不能保证new
分配内存的池与free()
要返回内存的池相同。想象一下,malloc()
和new
在每个分配块的开头使用几个字节的额外内存来指定块的大小。此外,想象一下,malloc()
和new
对此信息使用不同的格式 - 例如,malloc()
使用字节数,但new
使用4字节长字的数量(仅举例)。现在,如果您使用malloc()
进行分配并使用delete
进行释放,则delete
期望的信息将无效,并且您将得到一个已损坏的堆。