C++ delete[] 如何“知道”操作数数组的大小?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/197675/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How does delete[] "know" the size of the operand array?
提问by VolkerK
Foo* set = new Foo[100];
// ...
delete [] set;
You don't pass the array's boundaries to delete[]
. But where is that information stored? Is it standardised?
您不会将数组的边界传递给delete[]
. 但是这些信息存储在哪里呢?是否标准化?
采纳答案by Peter Kühne
When you allocate memory on the heap, your allocator will keep track of how much memory you have allocated. This is usually stored in a "head" segment just before the memory that you get allocated. That way when it's time to free the memory, the de-allocator knows exactly how much memory to free.
当您在堆上分配内存时,您的分配器将跟踪您分配了多少内存。这通常存储在您分配的内存之前的“头”段中。这样,当需要释放内存时,解除分配器确切地知道要释放多少内存。
回答by Avt
ONE OF THE approaches for compilers is to allocate a little more memory and to store a count of elements in a head element.
编译器的一种方法是分配更多内存并在头元素中存储元素计数。
Example how it could be done:
示例如何完成:
Here
这里
int* i = new int[4];
compiler will allocate sizeof(int)*5
bytes.
编译器将分配sizeof(int)*5
字节。
int *temp = malloc(sizeof(int)*5)
Will store "4" in the first sizeof(int)
bytes
将在第一个sizeof(int)
字节中存储“4”
*temp = 4;
and set i
并设置 i
i = temp + 1;
So i
will points to an array of 4 elements, not 5.
So i
will 指向一个包含 4 个元素的数组,而不是 5 个。
And deletion
并删除
delete[] i;
will be processed in the following way:
将按以下方式处理:
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)
回答by Daemin
The information is not standardised. However in the platforms that I have worked on this information is stored in memory just before the first element. Therefore you could theoretically access it and inspect it, however it's not worth it.
信息不规范。但是,在我处理过的平台中,此信息存储在第一个元素之前的内存中。因此,理论上您可以访问它并检查它,但它不值得。
Also this is why you must use delete [] when you allocated memory with new [], as the array version of delete knows that (and where) it needs to look to free the right amount of memory - and call the appropriate number of destructors for the objects.
这也是为什么当您使用 new [] 分配内存时必须使用 delete [],因为 delete 的数组版本知道(以及在哪里)它需要寻找释放适当数量的内存 - 并调用适当数量的析构函数为对象。
回答by Francisco Soto
Basically its arranged in memory as:
基本上它在内存中排列为:
[info][mem you asked for...]
[信息][你要求的记忆...]
Where info is the structure used by your compiler to store the amount of memory allocated, and what not.
其中 info 是编译器用来存储分配的内存量的结构,什么不是。
This is implementation dependent though.
不过,这取决于实现。
回答by jeffm
This isn't something that's in the spec -- it's implementation dependent.
这不是规范中的内容——它依赖于实现。
回答by MSN
It's defined in the C++ standard to be compiler specific. Which means compiler magic. It can break with non-trivial alignment restrictions on at least one major platform.
它在 C++ 标准中定义为特定于编译器。这意味着编译器魔法。它可以打破至少一个主要平台上的非平凡对齐限制。
You can think about possible implementations by realizing that delete[]
is only defined for pointers returned by new[]
, which may not be the same pointer as returned by operator new[]
. One implementation in the wild is to store the array count in the first int returned by operator new[]
, and have new[]
return a pointer offset past that. (This is why non-trivial alignments can break new[]
.)
您可以通过意识到delete[]
仅为 返回的指针定义它来考虑可能的实现,该指针new[]
可能与 返回的指针不同operator new[]
。在野外的一个实现是将数组计数存储在由 返回的第一个 int 中operator new[]
,并new[]
返回一个指针偏移量。(这就是为什么非平凡的对齐可能会中断new[]
。)
Keep in mind that operator new[]/operator delete[]
!=new[]/delete[]
.
请记住operator new[]/operator delete[]
!= new[]/delete[]
。
Plus, this is orthogonal to how C knows the size of memory allocated by malloc
.
另外,这与 C 如何知道由 分配的内存大小是正交的malloc
。
回答by Joel Coehoorn
Because the array to be 'deleted' should have been created with a single use of the 'new' operator. The 'new' operation should have put that information on the heap. Otherwise, how would additional uses of new know where the heap ends?
因为要“删除”的数组应该是使用一次“new”运算符创建的。'new' 操作应该将该信息放在堆上。否则,new 的其他用途如何知道堆在哪里结束?
回答by Andre
It is not standardized. In Microsoft's runtime the new operator uses malloc() and the delete operator uses free(). So, in this setting your question is equivalent to the following: How does free() know the size of the block?
它不是标准化的。在 Microsoft 的运行时中,new 运算符使用 malloc(),而 delete 运算符使用 free()。因此,在这种情况下,您的问题相当于以下内容:free() 如何知道块的大小?
There is some bookkeeping going on behind the scenes, i.e. in the C runtime.
幕后有一些簿记工作,即在 C 运行时中。
回答by Chris Jefferson
This is a more interesting problem than you might think at first. This reply is about one possible implementation.
这是一个比您最初想象的更有趣的问题。这个回复是关于一种可能的实现。
Firstly, while at some level your system has to know how to 'free' the memory block, the underlying malloc/free (which new/delete/new[]/delete[] generally call) don't always remember exactly how much memory you ask for, it can get rounded up (for example, once you are above 4K it is often rounded up to the next 4K-sized block).
首先,虽然在某种程度上您的系统必须知道如何“释放”内存块,但底层的 malloc/free(通常调用 new/delete/new[]/delete[])并不总是准确地记住多少内存您要求,它可以四舍五入(例如,一旦超过 4K,它通常会四舍五入到下一个 4K 大小的块)。
Therefore, even if could get the size of the memory block, that doesn't tell us how many values are in the new[]ed memory, as it can be smaller. Therefore, we do have to store an extra integer telling us how many values there are.
因此,即使可以获取内存块的大小,也不能告诉我们 new[]ed 内存中有多少个值,因为它可以更小。因此,我们必须存储一个额外的整数,告诉我们有多少个值。
EXCEPT, if the type being constructed doesn't have a destructor, then delete[] doesn't have to do anything except free the memory block, and therefore doesn't have to store anything!
除了,如果正在构造的类型没有析构函数,则 delete[] 除了释放内存块之外不需要做任何事情,因此不需要存储任何东西!