new []和delete []调用多少次来分配和取消分配内存?

时间:2018-09-28 05:54:57

标签: c++ memory constructor allocation

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[]一样,它是否在每次析构函数调用时都会释放?

3 个答案:

答案 0 :(得分:17)

您正在混合两个不同的概念:

  1. 内存分配/取消分配
  2. 对象构造/破坏

newdelete对我们都有帮助。

new Cell[5];

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

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

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

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

当您不想使用对象并将其从堆内存中释放时,必须使用delete [] cells指令。然后,cells指向的5个对象将在对象从内存中删除之前调用5个析构函数执行某些操作,但是cells仍存在于堆栈存储器中,并且可以用于指向另一个Cell对象(仅当cells超出其范围时,cells才会从区域中删除,现在堆内存上只有5个对象被删除)。这样您可以看到5行Cell being freed!