2011-07-13 35 views
2

可能重复:
How does delete[] know it's an array? (C++)
How does delete[] “know” the size of the operand array?C++数组和动态存储器

假设我们有下面的类的100种元素的

class Data 
{ 
public: 
    Data() : i(new int) { *i = 0; } 
    ~Data() { delete i; } 

private: 
    int *i; 
}; 

现在我们创建阵列键入数据

Data* dataArray = new Data[100]; 

我们知道,运营商新将调用数据构造为100个对象,因为它知道多少对象创建的,现在让我们删除这个数组,如果说delete dataArray为第一对象的析构函数只会被调用,即使我们知道我们释放的100个对象的内存会导致内存泄漏,因为它们被分配为一个块,但是如果我们说delete[] dataArray将会调用100个对象的析构函数,但这是一个动物记忆, t指定了那里有多少对象,并且据我所知,阵列没有开销来知道它中有多少对象,那么运行时环境如何知道在释放内存之前要破坏的对象的数量?

+0

分配器在分配的块上添加了一些神奇的数字,它告诉有多少元素 - 实际的实现取决于编译器 – stijn

+0

哇,问题名称中的方括号很糟糕。 – mkb

+0

http://stackoverflow.com/questions/197675/how-does-delete-know-the-size-of-the-operand-array < - 这可能是一个更好的候选人的重复通知 – bdonlan

回答

6

首先,delete dataArray是非法的。它可能摧毁第一个对象。它可能什么都不做。它可能会崩溃。它可能会通过你的鼻子召唤恶魔。不要这样做。

至于delete []如何确定要存储多少个元素,它取决于C++库的实现。通常在第一个元素之前有一个元素计数(这可能是元数据的一部分,它总是与动态分配相关联,或者可能是为delete []添加的额外数据); delete []实现将查看此计数以确定调用析构函数的次数;它会在实际释放内存之前将指针调整到元素计数之前的位置(这是导致delete dataArray可能崩溃的原因之一)。

1

这取决于编译器做什么,但基本上2个选择:

  • 存储数据只是实际的对象(数组大小,分配的大小)之前,一拉的malloc
  • 保留与数组大小关联的全局指针映射。
0

这就是为什么您需要在每个特定情况下使用operator deleteoperator delete[]。他们是不可互换他们做不同的事情。该实现保留了关于这些操作员使用的每个内存块的一些编译器/库特定的簿记信息。