新与新(以 malloc 为特色!)
在 C++ 中,标准做法是始终使用 new
而不是 malloc()
。但是,在这个 问题 中,重载 的最便携方法new
运算符在避免特定于平台的代码的同时,会在其中调用 malloc()
来进行实际分配。
重载时,将调用构造函数并保持类型安全。此外,您还可以监视和控制内存的分配方式。
我的问题是,当以这种方式使用时,在 C++ 中使用 malloc()
是否还有任何缺点?
In C++, it's standard to always use new
over malloc()
. However, in this question, the most portable way of overloading the new
operator while avoiding platform specific code is to place a call to malloc()
within it to do the actual allocation.
When overloaded, constructors are called and type-safety is kept. In addition, you can monitor and control how memory is allocated.
My question, when used in this capacity, are there still any downsides to using malloc()
within C++?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
如果您希望覆盖
new
和delete
,那么您几乎必须使用malloc
和free
。这就是它应该如何完成的。不要害怕。在
new()
实现之外使用malloc()
的缺点仍然存在。If you wish to override
new
anddelete
then you pretty much have to usemalloc
andfree
. That's how it is meant to be done. Do not be afraid.The downsides of using
malloc()
outside of the implementation ofnew()
remain.我能想到的最大缺点是您无法在使用
malloc()
分配的指针上显式调用delete
或delete []
> 不调用未定义的行为。如果您打算采用高度不推荐的路径并使用malloc()
为 C++ 对象显式分配内存,那么您仍然需要调用placement new
为了正确调用构造函数来初始化由malloc()
分配的内存位置。如果malloc()
上没有operator new
包装器,您还必须进行测试以确保不会获得NULL
返回值,并创建一些代码来处理您在没有抛出异常的情况下执行的情况。如果您只是尝试使用 memcpy() 等 C 库函数将 C++ 对象复制到由 malloc() 分配的堆内存中,这也非常危险,并且可能会导致许多未定义的行为。此外,由于您使用了
placement new
来构造对象,因此您必须为动态分配的对象显式调用析构函数,然后显式调用free()
指针。如果处理不当,这又可能会导致各种问题,特别是如果您想使用多态类型和虚拟基类。如果您打算仅使用
malloc()
和free()
,避免未定义行为陷阱的一个不错的经验法则是保留您分配和释放的对象malloc()
和free()
到 POD 类型。这意味着非多态结构或类没有用户定义的构造函数、析构函数、复制构造函数、赋值运算符、私有/受保护的非静态数据成员或基类,以及所有非静态数据成员struct/class 本身就是 POD 类型。由于 POD 类型基本上是 C 风格的结构(但具有定义非静态方法和 this 指针的附加功能),因此您可以安全地使用它们进行 C 风格的内存管理。The biggest downside I can think off is you can't explicitly call
delete
ordelete []
on a pointer that has been allocated usingmalloc()
without invoking undefined behavior. If you are going to go the highly un-recommended path and usemalloc()
to allocate memory explicitly for C++ objects, then you are still going to have to callplacement new
in order to properly call a constructor to initialize the memory location allocated bymalloc()
. Without anoperator new
wrapper onmalloc()
, you'll also have to test to make sure you do not get aNULL
return value, and create some code to handle cases where you do without the benefit of throwing an exception. It's also very dangerous, and can incur a number of undefined behaviors, if you simply tried to use C-library functions likememcpy()
to copy C++ objects into heap memory allocated withmalloc()
.Furthermore, because you utilized
placement new
for your object construction, you are going to have to explicitly call the destructuors for your dynamically allocated objects, and then explicitly callfree()
on the pointers. This again can cause all sorts of problems if it's not handled correctly, especially if you wanted to work with polymorphic types and virtual base-classes.If you are going to work with just
malloc()
andfree()
, a nice rule of thumb to avoid undefined behavior pitfalls is to keep the objects you allocate and deallocate withmalloc()
andfree()
to POD-types. That means non-polymorphic structs or classes with no user-defined constructors, destructors, copy-constructors, assignment operators, private/protected non-static data-members, or base-classes, and all the non-static data-members of the struct/class are POD-types themselves. Since POD-types are basically C-style structs (but with the added ability to define non-static methods and athis
pointer), you can safely do C-style memory management with them.您自己说过...直接在 C++ 代码中使用
malloc
/free
的缺点是构造函数和析构函数不会运行;使用new
/delete
确保构造函数和析构函数运行。但是,通过 new/delete 运算符间接使用 malloc 并没有什么问题。You stated it yourself... the downside to using
malloc
/free
directly in C++ code is that constructors and destructors will not be run; usingnew
/delete
ensures that constructors and destructors are run. However, there is nothing wrong with indirectly using malloc via the new/delete operators.