在C++中有new
和delete
,那么malloc
和free
的用途是什么呢?我猜两者的作用是相同的。
在C++中有new
和delete
,那么malloc
和free
的用途是什么呢?我猜两者的作用是相同的。
new
调用构造函数,malloc
只分配内存。new
和 free
以及使用 malloc
和 delete
)是 未定义行为。new
和 delete
,malloc
和 free
是为了与 C 兼容而存在的。malloc
和free
来代替new
和delete
。一个可以想到的场景是:如果你不想通过隐式构造函数调用来初始化内存,并且只需要为放置new确保内存分配,那么使用malloc
和free
而不是new
和delete
是完全可以的。malloc
和new
是不同的!两个重要的区别是:
new
保证调用类的构造函数来初始化类成员,而malloc
则不会。在malloc
之后,必须进行额外的memset
或相关函数调用来初始化分配的内存以执行有意义的操作。
一个巨大的优势是,在new
中,你不需要在每次分配之后检查NULL
,只需封装异常处理程序即可完成工作,这样可以节省冗余的错误检查,而malloc
则需要。
new char[]
有一些(非常小的)开销。也就是说,它会在内存块中存储分配的字符数。 - Nicol Bolasfree
函数如何知道要释放多少内存?malloc
函数会保存分配的字节数。 - MSaltersnew MyClass []
这样的语法必须存储确切的计数,以便调用正确数量的解构函数,因为否则无法推导出这些信息。 new char []
也可能会这样做(出于正交性的原因 - 它不需要计数); 我所知道的那些没有这样做。 - James Kanzemalloc()
和::operator new()
之间的一个重要区别是,你可以合法地替换::operator new()
函数,而malloc()
保证在其实现中不会使用::operator new()
函数,因此你可以在operator new()
的重载中使用malloc()
函数。(形式上,malloc()
和free()
是唯一拥有这种保证的函数。在我的::operator new()
的实现中,我倾向于假设像memset
和memcpy
这样的函数也不会调用::operator new()
。) - James Kanzenew char[N]
对于所有可能的类型都正确对齐(因此,new char[N]
的返回值的对齐要求大于new int[N]
的对齐要求)。然而,从可读性的角度来看,当目标是获取原始内存时,我更喜欢看到使用::operator new(N)
。 - James Kanzenew
和delete
时,我假设您指的是表达式,而不是operator new
和operator delete
函数。 new
和delete
表达式与malloc
和free
无关,仅偶尔管理内存;它们的主要作用是管理对象生命周期:一个new
表达式将调用operator new
函数获取内存,然后调用构造函数;一个delete
表达式将在调用operator delete
释放内存之前调用析构函数。大多数情况下,应该创建对象,而不仅仅是分配内存,这意味着只使用表达式。std::vector
这样的东西是一个经典示例,其中你会一次为许多对象分配空间,但一次只构造一个。在这种情况下,您将使用operator new
函数进行分配,并使用放置new进行初始化;在另一端,您将显式调用构造函数(类似p->~T()
)进行销毁,并使用operator delete
函数释放内存。malloc
和free
。第一种是实现自己的替代::operator new
和::operator delete
函数。(我经常用调试版本替换全局::operator new
和::operator delete
,以跟踪分配、在分配的内存周围放置守卫区等)另一种情况是与用C编写的遗留库交互:如果库说要传递由malloc
分配的内存的指针(因为它将使用free
自行释放),或更常见的是返回由malloc
分配的内存的指针,您需要释放,则必须使用malloc
和free
。(更好的库将提供其自己的分配和释放函数,这些函数几乎与new
和delete
运算符所做的相同,但总会有像strdup()
这样的东西。)malloc
和free
,以及其他任何内容。实际上,有很多函数根本不会分配内存(例如memset
);我认为它们也是安全的。实际上,您可能可以放心使用整个C库,但我的调试实现会检查递归,并且如果正在递归调用::operator new
,则不会使用超过一个malloc
、memset
和memcpy
(因此,如果fprintf
确实使用::operator new
,我就不会遇到无限递归)。 - James Kanze
new
和delete
的理由并不完全正确(特别是在Nicol回复你的评论后)。 - Alok Savenew char[]
的可能原因,但没有理由不使用我在他回复的评论中提到的::operator new
。仍然没有必要使用malloc
。 - user743382