6

看到一个使用函数的例子:cpp中的delete,没完全看懂。代码是:

class Name {
    const char* s;
    //...
};

class Table {
      Name* p;
      size_t sz;
public:
      Table(size_t s = 15){p = new Name[sz = s]; }
      ~Table { delete[] p; }
};

该命令的确切操作是什么:delete[] p;

我认为目的是删除容器表中的所有指针。

中的括号delete[]给我一个线索,它删除了一个指向 Name 的指针数组,但没有指定数组的大小,那么析构函数如何“知道”要删除多少个指针?

4

2 回答 2

14

delete不是函数,而是运算符。

delete表达式 using[]会破坏使用创建的对象并new ... []释放相关的内存。delete[]必须用于由new ... [];返回的指针 non-arraydelete仅在由 non-array 返回的指针上new。使用不匹配的delete形式总是不正确的。

(您的代码中缺少)中的delete表达式将破坏动态创建的对象数组,确保为数组的每个成员调用析构函数。~Table()()NameName

实现某种机制来记录分配给new ... []程序员的数组中的元素数量是由实现决定的,而不必担心这一点。

在许多实现中,数组元素具有非平凡的析构函数,new[]表达式将分配额外的空间来在所有数组成员的空间之前记录元素计数。delete[]然后在用于确保调用正确数量的析构函数时查找此隐藏计数。这只是一个实现细节,但其他实现也是可能的。

于 2010-08-07T12:43:55.123 回答
1

简而言之,delete[]知道它正在删除的数组的大小,因为它是必需的。

因为 C++ 语言标准规定它必须知道。因此,当您分配数组时,系统将大小存储在delete[]可以找到它的地方。

一种选择是分配比需要更多的字节。使用第一个字节来指定大小,然后不是返回指向第一个分配字节的指针,而是返回一个指向超过大小字段的第一个字节的指针。

然后delete[]只需从指针中减去几个字节即可找到大小。

另一种选择可能是拥有一个 global map<void*, int>,其中 key 是指向内存分配的指针,而 value 是该分配的大小。还有很多其他方法delete[]可以找出大小。C++ 标准没有指定使用哪一个。它只是说delete[]必须知道大小,并将其留给实施者来弄清楚如何实现它。

于 2010-08-07T12:48:49.260 回答