【发布时间】:2012-04-15 20:44:49
【问题描述】:
当我们在 C++ 中有 new 和 delete 时,malloc 和 free 有什么用。我猜free 和delete 的功能是一样的。
【问题讨论】:
标签: c++ memory-management
当我们在 C++ 中有 new 和 delete 时,malloc 和 free 有什么用。我猜free 和delete 的功能是一样的。
【问题讨论】:
标签: c++ memory-management
它们不一样。 new 调用构造函数,malloc 只是分配内存。
另外,它是未定义的行为混合两者(即使用new 与free 和malloc 与delete)。
在 C++ 中,出于与 C 的兼容性原因,您应该使用 new 和 delete、malloc 和 free。
【讨论】:
new 和 delete 的理由并不完全正确(尤其是在 Nicol 回复您的评论之后。)
new char[] 的可能原因,但没有理由不使用::operator new,我在他回复的评论中提到了这一点。还是不用malloc。
在 C++ 中,使用malloc 和free 而不是new& delete 很少有用。
我能想到的一个场景是:
如果您不想通过隐式构造函数调用来初始化您的内存,并且只需要为 placement new 确保内存分配,那么使用 malloc 和 free 是完全可以的而不是new 和delete。
另一方面,重要的是要知道 malloc 和 new 不一样!
两个重要的区别是:
new 保证调用您的类的构造函数来初始化类成员,而 malloc 不保证,必须执行额外的 memset 或相关函数调用发布 malloc 来初始化分配内存来做一些有意义的事情。
一个很大的优势是,对于new,您无需在每次分配后检查NULL,与malloc 不同,只需包含异常处理程序即可完成这项工作,从而为您节省冗余错误检查。
【讨论】:
operator new 就足够了,或者new char[n]。 (为此使用 malloc 并没有错,但这不是必需的。)
new char[] 有一些(非常小的)开销。即,它存储在内存块中分配的字符数。
free 怎么知道要释放多少? malloc 也会存储分配的字节数。
new MyClass[] 这样的东西通常也必须存储确切的计数,以便调用正确数量的析构函数,因为无法以其他方式导出此信息。 new char[] 也可以这样做(出于正交性的原因——它不需要计数);我认识的人不知道。
malloc() 和 ::operator new() 之间的一个重要区别。您可以合法地替换::operator new(),并且保证malloc() 在其实现中不会使用::operator new(),因此您可以在operator new() 的覆盖中使用malloc()。 (正式地,malloc 和 free 是唯一具有此保证的函数。在我对 ::operator new() 的实现中,它倾向于假设像 memset 和 memcpy 这样的函数也不会调用 ::operator new()。 )
首先,当您谈到 new 和 delete 时,我假设您的意思是
表达式,而不是 operator new 和 operator delete 函数。
new 和 delete 表达式与 malloc 和
free,只是顺便管理内存;他们的主要作用是
管理对象生命周期:new 表达式将调用 operator new
函数获取内存,然后调用构造函数;一个delete
表达式将在调用operator delete 之前调用析构函数
释放内存。在大多数情况下,对象应该是创建的,并且
不是简单的allocated,这意味着只使用表达式。
在极少数情况下,人们希望将分配和
初始化(创建);实现像std::vector 这样的东西是一个
经典示例,您将一次性分配许多对象,但是
一次只能构建一个。在这种情况下,您将使用operator
new 函数进行分配,并使用placement new 进行初始化;在
在另一端,您将显式调用构造函数(类似于
p->~T()) 用于销毁,并使用operator delete 函数
释放内存。
顺便说一句,我只能想到两种情况,您可以使用 malloc 和
free 在 C++ 中。首先是实现自己的替换
::operator new 和 ::operator delete 函数。 (我经常更换
全局 ::operator new 和 ::operator delete 带调试
跟踪分配的版本,在分配的周围放置保护区
内存等)另一个是与遗留库交互时
用 C 编写:如果库说要传递一个指向已分配内存的指针
由malloc (因为它会使用free 自行释放它),或更多
通常,返回一个指向由malloc 分配的内存的指针,它
您应该免费,那么您必须使用malloc 和free。 (这
更好的图书馆将提供自己的分配和释放
函数,它们或多或少地完成了 new 和 delete 运算符的作用
做,但总会有strdup()之类的东西。)
【讨论】:
malloc 和 free,仅此而已。实际上,有很多函数根本不会分配内存(比如memset);我也认为它们是安全的。实际上,您可能对整个 C 库是安全的,但我的调试实现确实会检查递归,并且如果 ::operator new 被递归调用(所以如果fprintf 确实使用::operator new,我不会以无限递归结束)。