【问题标题】:Why use malloc/free, when we have new/delete?当我们有 new/delete 时,为什么要使用 malloc/free?
【发布时间】:2012-04-15 20:44:49
【问题描述】:

当我们在 C++ 中有 newdelete 时,mallocfree 有什么用。我猜freedelete 的功能是一样的。

【问题讨论】:

    标签: c++ memory-management


    【解决方案1】:

    它们不一样。 new 调用构造函数,malloc 只是分配内存。

    另外,它是未定义的行为混合两者(即使用newfreemallocdelete)。

    在 C++ 中,出于与 C 的兼容性原因,您应该使用 newdeletemallocfree

    【讨论】:

    • 好的。但它们都用于内存管理。那么什么时候用new,什么时候用malloc呢?
    • @Parag “在 C++ 中,你应该使用 new 和 delete”回答这个问题吗?不要使用 malloc/free。
    • @hvd:这不是正确的建议。您在 C++ 中仅使用 newdelete 的理由并不完全正确(尤其是在 Nicol 回复您的评论之后。)
    • @Als Nicol 的回复是不使用new char[] 的可能原因,但没有理由不使用::operator new,我在他回复的评论中提到了这一点。还是不用malloc
    【解决方案2】:

    在 C++ 中,使用mallocfree 而不是new& delete 很少有用。

    我能想到的一个场景是:

    如果您不想通过隐式构造函数调用来初始化您的内存,并且只需要为 placement new 确保内存分配,那么使用 mallocfree 是完全可以的而不是newdelete

    另一方面,重要的是要知道 mallocnew 不一样!
    两个重要的区别是:

    • new 保证调用您的类的构造函数来初始化类成员,而 malloc 不保证,必须执行额外的 memset 或相关函数调用发布 malloc 来初始化分配内存来做一些有意义的事情。

    • 一个很大的优势是,对于new,您无需在每次分配后检查NULL,与malloc 不同,只需包含异常处理程序即可完成这项工作,从而为您节省冗余错误检查。

    【讨论】:

    • 当然,但是明确调用operator new 就足够了,或者new char[n]。 (为此使用 malloc 并没有错,但这不是必需的。)
    • @hvd: new char[] 有一些(非常小的)开销。即,它存储在内存块中分配的字符数。
    • @NicolBolas:free 怎么知道要释放多少? malloc 也会存储分配的字节数。
    • @MSalters 或一些在内存中查找以下块的方法。像new MyClass[] 这样的东西通常也必须存储确切的计数,以便调用正确数量的析构函数,因为无法以其他方式导出此信息。 new char[] 也可以这样做(出于正交性的原因——它不需要计数);我认识的人不知道。
    • @Als malloc()::operator new() 之间的一个重要区别。您可以合法地替换::operator new(),并且保证malloc() 在其实现中不会使用::operator new(),因此您可以在operator new() 的覆盖中使用malloc()。 (正式地,mallocfree 是唯一具有此保证的函数。在我对 ::operator new() 的实现中,它倾向于假设像 memsetmemcpy 这样的函数也不会调用 ::operator new()。 )
    【解决方案3】:

    首先,当您谈到 newdelete 时,我假设您的意思是 表达式,而不是 operator newoperator delete 函数。 newdelete 表达式与 mallocfree,只是顺便管理内存;他们的主要作用是 管理对象生命周期:new 表达式将调用 operator new 函数获取内存,然后调用构造函数;一个delete 表达式将在调用operator delete 之前调用析构函数 释放内存。在大多数情况下,对象应该是创建的,并且 不是简单的allocated,这意味着只使用表达式。

    在极少数情况下,人们希望将分配和 初始化(创建);实现像std::vector 这样的东西是一个 经典示例,您将一次性分配许多对象,但是 一次只能构建一个。在这种情况下,您将使用operator new 函数进行分配,并使用placement new 进行初始化;在 在另一端,您将显式调用构造函数(类似于 p->~T()) 用于销毁,并使用operator delete 函数 释放内存。

    顺便说一句,我只能想到两种情况,您可以使用 mallocfree 在 C++ 中。首先是实现自己的替换 ::operator new::operator delete 函数。 (我经常更换 全局 ::operator new::operator delete 带调试 跟踪分配的版本,在分配的周围放置保护区 内存等)另一个是与遗留库交互时 用 C 编写:如果库说要传递一个指向已分配内存的指针 由malloc (因为它会使用free 自行释放它),或更多 通常,返回一个指向由malloc 分配的内存的指针,它 您应该免费,那么您必须使用mallocfree。 (这 更好的图书馆将提供自己的分配和释放 函数,它们或多或少地完成了 newdelete 运算符的作用 做,但总会有strdup()之类的东西。)

    【讨论】:

    • 对于那些对答案中所述的第一次使用感兴趣的人,How should I write ISO C++ Standard conformant custom new and delete operators? 是一个很好的阅读。
    • @Als 为了 100% 的一致性,您可以使用语言 mallocfree,仅此而已。实际上,有很多函数根本不会分配内存(比如memset);我也认为它们是安全的。实际上,您可能对整个 C 库是安全的,但我的调试实现确实会检查递归,并且如果 ::operator new 被递归调用(所以如果fprintf 确实使用::operator new,我不会以无限递归结束)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-02
    • 2023-04-04
    • 2016-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多