【问题标题】:How many times do new [] and delete[] make calls to allocate and deallocate memory?new [] 和 delete[] 调用多少次来分配和释放内存?
【发布时间】:2018-09-28 05:54:56
【问题描述】:

在C++中,每次使用new []或delete [],分别分配或释放多少次内存?我的问题更具体地说是在具有各自构造函数和析构函数的类上使用它们。

比如,上下面的课:

#include <iostream>

class Cell
{
public:
    Cell() : _value(2)
    {
        std::cout << "Cell being made!\n";
    }
    ~Cell()
    {
        std::cout << "Cell being freed!\n";
    }

    const int& getVal() const
    {
        return _value;
    }
private:
    int _value;
};

现在,假设需要一个该类类型的数组,并使用new[],如下所示

Cell* cells = new Cell[5];

当它在可执行文件或程序中运行时,我还看到打印到标准输出的以下内容:

Cell being made!
Cell being made!
Cell being made!
Cell being made!
Cell being made!

随后当delete[] 被cells 指针调用时,我看到了:

Cell being freed!
Cell being freed!
Cell being freed!
Cell being freed!
Cell being freed!

我的问题是,在每个构造函数调用中,内存大小是否等于分配的一个类实例?比如new Cell[5]会分配内存5次吗?或者它是否分配一次然后对构造函数进行 5 次调用作为函数调用?与delete[] 相同,是否在每次析构函数调用时释放?

【问题讨论】:

  • 请注意,通常有两个分配级别,来自new 和来自操作系统。 new 被实现为子分配器是很常见的;它只向操作系统询问大内存块,并在程序需要更小的内存块时对其进行细分。

标签: c++ memory constructor allocation


【解决方案1】:

您混合了两个不同的概念:

  1. 内存分配/释放
  2. 对象构造/销毁

new 和 delete 为我们做这两件事。

new Cell[5];

所有 5 个对象所需的总内存在一次内存分配操作中分配。不能是 5 个分配,因为 5 个不同的分配不能保证连续的空间。

为 5 个对象分配内存后,new 必须通过调用默认构造函数来初始化 5 个对象。这里我们有 5 个单独的构造函数调用。

delete [] cells 期间发生了类似的事情。它必须通过调用 5 个不同对象的析构函数来销毁 5 个对象。然后在一个释放操作中释放所有分配的内存。

【讨论】:

  • 没错。另一个证明这一点的例子:Cell c; 将导致构造函数和析构函数被调用,尽管没有在堆上分配任何内存。
【解决方案2】:

如果(关键字而不是运算符)new [] 成功,它会分配一个足够大的块来容纳所有对象,然后将对象构造到该块中。 同样,(关键字)delete [] 将为数组中的每个对象调用析构函数,然后释放整个块。

new 和 delete(以及 new [] 和 delete[])运算符执行实际的分配/解除分配,并且将在任何给定的 new/new[] 和 delete/delete[] 关键字的使用中调用一次。

【讨论】:

    【解决方案3】:

    指令Cell* cells = new Cell[5]; 意味着您创建了5 个连续位于堆区域(主内存)上的单元对象。而cells 是位于堆栈区域(主内存)上的指针,它指向对象(cells 将只存储第一个对象的地址)。之后,每个对象都会调用默认构造函数来初始化它的值,所以你会看到 5 行 Cell being made!。

    当您不想使用对象并想从堆内存中释放它时,您必须使用delete [] cells 指令。然后,cells 指向的 5 个对象将在对象从内存中删除之前调用 5 个析构函数来做一些事情,但 cells 仍然存在于 Stack 内存中,它可以用来指向另一个 Cell 对象(cells仅当cells 超出其范围时才会从区域中删除,现在仅删除堆内存上的 5 个对象)。所以你可以看到5行Cell being freed!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-09
      • 1970-01-01
      • 1970-01-01
      • 2020-08-25
      相关资源
      最近更新 更多