Foo* set = new Foo[100];
// ...
delete [] set;
Run Code Online (Sandbox Code Playgroud)
您没有将数组的边界传递给delete[]
.但是这些信息存储在哪里?它是标准化的吗?
Qua*_*ete 168
在堆上分配内存时,分配器将跟踪已分配的内存量.这通常存储在您分配的内存之前的"head"段中.这样,当释放内存时,解除分配器确切地知道要释放多少内存.
Avt*_*Avt 22
编译器的一种方法是分配更多的内存并在头元素中存储元素的数量.
示例如何完成:
这里
int* i = new int[4];
Run Code Online (Sandbox Code Playgroud)
编译器将分配sizeof(int)*5
字节.
int *temp = malloc(sizeof(int)*5)
Run Code Online (Sandbox Code Playgroud)
将在第一个sizeof(int)
字节中存储"4"
*temp = 4;
Run Code Online (Sandbox Code Playgroud)
并设定 i
i = temp + 1;
Run Code Online (Sandbox Code Playgroud)
所以i
将指向一个包含4个元素的数组,而不是5个元素.
并删除
delete[] i;
Run Code Online (Sandbox Code Playgroud)
将按以下方式处理:
int *temp = i - 1;
int numbers_of_element = *temp; // = 4
... call destructor for numbers_of_element elements
... that are stored in temp + 1, temp + 2, ... temp + 4 if needed
free (temp)
Run Code Online (Sandbox Code Playgroud)
信息不规范.但是,在我处理过的平台中,这些信息存储在第一个元素之前的内存中.因此,理论上你可以访问并检查它,但它不值得.
这就是为什么你在使用new []分配内存时必须使用delete [],因为delete的数组版本知道它需要查找(以及在哪里)释放适当数量的内存 - 并调用适当数量的析构函数对象.
它在 C++ 标准中定义为特定于编译器。这意味着编译器魔法。它可以打破至少一个主要平台上的非平凡对齐限制。
您可以通过意识到delete[]
仅为 返回的指针定义它来考虑可能的实现,该指针new[]
可能与 返回的指针不同operator new[]
。在野外的一个实现是将数组计数存储在由 返回的第一个 int 中operator new[]
,并new[]
返回一个指针偏移量。(这就是为什么非平凡的对齐可能会中断new[]
。)
请记住operator new[]/operator delete[]
!= new[]/delete[]
。
另外,这与 C 如何知道由 分配的内存大小是正交的malloc
。
归档时间: |
|
查看次数: |
34362 次 |
最近记录: |