在C ++中,始终使用new
而不是malloc()
是标准的。但是,在此question中,在避免使用平台特定代码的同时重载new
运算符的最便携方式是在其中调用malloc()
来进行实际分配。
重载时,调用构造函数并保持类型安全。此外,您还可以监视和控制内存的分配方式。
我的问题是,在这个容量中使用时,在C ++中使用malloc()
仍然有任何缺点吗?
答案 0 :(得分:7)
如果您希望覆盖new
和delete
,那么您几乎必须使用malloc
和free
。这就是它的意图。不要害怕。
在malloc()
的实施之外使用new()
的缺点仍然存在。
答案 1 :(得分:5)
我能想到的最大缺点是你不能在使用delete
分配的指针上显式调用delete []
或malloc()
而不调用未定义的行为。如果您打算使用高度不推荐的路径并使用malloc()
为C ++对象显式分配内存,那么您仍然需要调用placement new
才能正确调用构造函数来初始化由malloc()
分配的内存位置。如果operator new
上没有malloc()
包装,您还必须进行测试,以确保没有获得NULL
返回值,并创建一些代码来处理没有抛出异常的好处。如果您只是尝试使用像memcpy()
这样的C库函数将C ++对象复制到分配有malloc()
的堆内存中,那么它也会非常危险,并且会产生许多未定义的行为。
此外,因为您使用placement new
进行对象构造,所以您必须为动态分配的对象显式调用析构函数,然后在指针上显式调用free()
。如果处理不当,这又会导致各种问题,特别是如果你想处理多态类型和虚拟基类。
如果您打算只使用malloc()
和free()
,那么避免未定义的行为陷阱的一个好的经验法则是保留您分配的对象并使用malloc()
和{取消分配{1}}到POD类型。这意味着非多态结构或类没有用户定义的构造函数,析构函数,复制构造函数,赋值运算符,私有/受保护的非静态数据成员或基类,以及所有非静态数据成员struct / class本身就是POD类型。由于POD类型基本上是C风格的结构(但具有定义非静态方法和free()
指针的附加功能),因此您可以安全地使用它们进行C风格的内存管理。
答案 2 :(得分:3)
你自己说过......在C ++代码中直接使用malloc
/ free
的缺点是构造函数和析构函数不会被运行;使用new
/ delete
可确保运行构造函数和析构函数。但是,通过new / delete运算符间接使用malloc没有任何问题。