简体   繁体   English

动态分配数组的大小

[英]size of dynamically allocated array

Is it true that a pointer assigned to the starting address of a dynamically allocated array does not have the information of the size of the array? 分配给动态分配的数组的起始地址的指针是否不具有数组大小的信息? So we have to use another variable to store its size for later processing the array through the pointer. 所以我们必须使用另一个变量来存储它的大小,以便稍后通过指针处理数组。

But when we free the dynamically allocated array, we don't specify the size, instead we just "free ptr" or "delete [] ptr". 但是当我们释放动态分配的数组时,我们不指定大小,而只是“free ptr”或“delete [] ptr”。 How could free or delete know the size of the array? 如何释放或删除知道数组的大小? Can we use the same scheme to avoid storing the size of the array in another variable? 我们可以使用相同的方案来避免将数组的大小存储在另一个变量中吗?

Thanks! 谢谢!

Yes, this is true. 是的,这是真的。

delete knows the size of the memory chunk because new adds extra information to the chunk (usually before the area returned to the user), containing its size, along with other information. delete知道内存块的大小,因为new会向块添加额外信息(通常在返回给用户的区域之前),包含其大小以及其他信息。 Note that this is all very much implementation specific and shouldn't be used by your code. 请注意,这些都是特定于实现的,不应该由您的代码使用。

So to answer your last question: No - we can't use it - it's an implementation detail that's highly platform and compiler dependent. 所以回答你的最后一个问题: - 我们不能使用它 - 它是一个高度平台和编译器相关的实现细节。


For example, in the sample memory allocator demonstrated in K&R2, this is the "header" placed before each allocated chunk: 例如,在K&R2中演示的示例内存分配器中,这是放置在每个已分配块之前的“标头”:

typedef long Align; /* for alignment to long boundary */

union header { /* block header */
  struct {
    union header *ptr; /* next block if on free list */
    unsigned size; /* size of this block */
  } s;

  Align x; /* force alignment of blocks */
};

typedef union header Header;

size is the size of the allocated block (that's then used by free , or delete ). size是已分配块的大小(然后由freedelete )。

The funny thing is that historically it was delete [20] arr; 有趣的是,从历史上看它是delete [20] arr; just as it is arr = new int[20] . 就像它是arr = new int[20] However practice proved that the information on size can be painlessly stored by the allocator, and since most people using it then stored it anyway, it was added to the standard. 然而,实践证明,分配器可以无痛地存储大小信息,并且由于大多数人使用它然后无论如何都存储它,它被添加到标准中。

What is more funny, and little known, is the fact that this "extended delete syntax" is in fact supported by a few C++ compilers (despite being incorrect even in face of the C++98 standard), although none require it. 更有趣,也鲜为人知的是,这种“扩展删除语法”实际上是由少数C ++编译器支持的(尽管即使面对C ++ 98标准也是如此),尽管没有人需要它。

int* arr = new int[20];
delete [20] arr;

The sad part about this all however is, that there's no standard-conforming way to retrieve that passed size for your own use :-/ 然而,关于这一切的可悲部分是,没有符合标准的方法来检索通过尺寸供您自己使用: - /

It is true that the array does not contain the size of the array, you have to store that information for later. 确实,数组不包含数组的大小,您必须存储该信息以供日后使用。 When deleting an array through delete or free it is the pointer to the allocated memory you pass. 通过deletefree删除数组时,它是指向您传递的已分配内存的指针。 The memory manager used (either by the system or your own custom from overriding new and delete) knows the memory area that is freed, and keeps track of it. 使用的内存管理器(由系统或您自己的自定义覆盖new和delete)知道释放的内存区域,并跟踪它。 Hope it makes sense. 希望它有意义。

Yes, it's true. 对,是真的。 This is part of why you should rarely try to deal with this directly, and use a standard container instead. 这是为什么你应该很少直接尝试处理这个问题的一部分,而是使用标准容器。 About the only time it makes sense to deal with it is if you decide to implement a container yourself (in which case you'll normally track the size information in your container's implementation). 关于处理它的唯一时间是你自己决定实现容器(在这种情况下,你通常会跟踪容器实现中的大小信息)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM