【问题标题】:Why are there two versions of operator new overload?为什么有两个版本的 operator new 重载?
【发布时间】:2015-04-02 12:30:24
【问题描述】:

newnew[] 分别重载命名为operator newoperator new[] 的原因是什么?由于它们都只用于分配一定数量的内存 - 为什么我要为它们各自编写不同的代码?

【问题讨论】:

  • new[] 还会在实际存储数组之前存储数组大小
  • 例如,您想为小对象创建一个内存池。而且您的池不支持分配对象数组。所以你保留operator new[] 默认。
  • 他们希望通过不需要在某处存储分配的大小,让实现有机会优化单个对象的分配。
  • 我认为这只需要在释放时调用适当数量的析构函数。但这不是隐式完成的吗?
  • delete[] 告诉实现它应该查看要销毁的对象的数量。但如果使用new,则可能不会存储此信息。

标签: c++ new-operator c++14 iso


【解决方案1】:

new 用于创建单个对象

int * foo = new int;  // now I have one int*

new[]用于创建多个对象并将它们放入连续的内存(数组)中

int * bar = new int[someIntegerValue];

使用 new 时,您需要确保将其与正确的 delete 调用相匹配。如果您使用new,则需要对delete 进行相应的调用,new[]delete[] 也是如此

int * foo = new int;  // now I have one int*
//more code...
// now that I'm done with foo
delete foo;

int * bar = new int[someIntegerValue];
//more code...
// now that I'm done with bar.
delete [] bar;

【讨论】:

  • 这并没有解释为什么有两个单独的重载。 new 可以重定向到 new[] 但只传递一个大小为 1 的对象。但事实并非如此。就是这个问题。
  • @NeilKirk 那不是让你分配一个 int 并删除[]它吗?
  • @Alex 也许,我指的是一种假设语言,而不是 C++
【解决方案2】:

内存分配优化,因为您不需要按照评论中的建议存储数组大小是不是的原因(事实上,operator new[] per 18.6.1.2 的默认行为是调用operator new 用于分配存储)。
此外,无论如何,每个实际实现中的每个分配都会存储分配大小(可以从中轻松推断出数组大小)。

您需要两个版本的new 的决定性原因是通常需要一个数组版本(出于显而易见的原因),但数组版本不能有初始化程序。然而,在一个新的表达式上有一个初始化器是非常可取的。因此,需要两个单独的版本。

此外,一些优化的分配器(例如 freelist)对于单个对象非常容易实现,但对于连续数组则很难实现。具有 10 个元素的空闲列表不一定有 10 个连续元素(甚至两个连续元素!),因此没有简单的方法可以可靠地进行数组分配。 这意味着如果没有new 的两个单独版本,您根本无法实现这样的事情。有两个版本,您仍然可以为一个版本使用自定义分配器,但不能为另一个版本。

作为免费提供的“奖励”,您可以单独覆盖(和=delete)这两个运算符,如果由于某种原因您希望处理它们显着不同或选择性地不希望允许一个其中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-25
    • 2011-08-30
    • 2011-01-11
    • 2021-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-29
    相关资源
    最近更新 更多