new vs. new (featuring malloc!)

new vs. new (featuring malloc!)

本文关键字:new malloc featuring vs      更新时间:2023-10-16

在c++中,总是使用new而不是malloc()是标准的。然而,在这个问题中,重载new操作符同时避免平台特定代码的最可移植的方法是在其中调用malloc()来进行实际分配。

当重载时,调用构造函数并保持类型安全。此外,您可以监视和控制如何分配内存。

我的问题是,当以这种方式使用时,在c++中使用malloc()是否还有任何缺点?

如果你想覆盖newdelete,那么你几乎必须使用mallocfree。这就是应该做的。不要害怕。

new()实现之外使用malloc()的缺点仍然存在。

我能想到的最大缺点是你不能显式地调用deletedelete []在一个指针上,已经使用malloc()分配而不调用未定义的行为。如果您打算采用极不推荐的方法,并使用malloc()显式地为c++对象分配内存,那么您仍然必须调用placement new,以便正确调用构造函数来初始化由malloc()分配的内存位置。如果在malloc()上没有operator new包装器,您还必须进行测试,以确保没有获得NULL返回值,并创建一些代码来处理没有抛出异常的情况。如果您只是尝试使用C库函数(如memcpy())将c++对象复制到由malloc()分配的堆内存中,这也是非常危险的,并且可能导致许多未定义的行为。

此外,由于您在对象构造中使用了placement new,因此必须显式地调用动态分配对象的析构函数,然后显式地调用指针上的free()。如果处理不当,这同样会导致各种各样的问题,特别是当您想要使用多态类型和虚拟基类时。

如果您只使用malloc()free(),那么避免未定义行为陷阱的一个很好的经验法则是将您使用malloc()free()分配和释放的对象保留为pod类型。这意味着没有用户定义的构造函数、析构函数、复制构造函数、赋值操作符、私有/受保护的非静态数据成员或基类的非多态结构或类,以及结构/类的所有非静态数据成员本身都是pod类型。由于pod类型基本上是c风格的结构(但增加了定义非静态方法和this指针的能力),因此可以安全地使用它们进行c风格的内存管理。

你自己说的…在c++代码中直接使用malloc/free的缺点是不会运行构造函数和析构函数;使用new/delete确保运行构造函数和析构函数。但是,通过new/delete操作符间接使用malloc并没有错。