动态分配数组的大小
分配给动态分配的数组的起始地址的指针是否不具有数组大小的信息? 所以我们必须使用另一个变量来存储它的大小,以便以后通过指针处理数组。
但是当我们释放动态分配的数组时,我们不指定大小,而只是“free ptr”或“delete [] ptr”。 如何释放或删除知道数组的大小? 我们可以使用相同的方案来避免将数组的大小存储在另一个变量中吗?
谢谢!
是的,这是真的。
delete
知道内存块的大小,因为new
会向块添加额外信息(通常在返回给用户的区域之前),包含其大小以及其他信息。 请注意,这些都是特定于实现的,您的代码不应该使用它。
所以回答你的最后一个问题: 不 – 我们不能使用它 – 它是一个高度平台和编译器相关的实现细节。
例如,在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
是已分配块的大小(然后由free
或delete
)。
有趣的是,从历史上看它是delete [20] arr;
就像它是arr = new int[20]
。 然而,实践certificate,分配器可以无痛地存储大小信息,并且由于大多数人使用它然后无论如何都存储它,它被添加到标准中。
更有趣,也鲜为人知的是,这种“扩展删除语法”实际上是由少数C ++编译器支持的(尽管即使面对C ++ 98标准也是如此),尽管没有人需要它。
int* arr = new int[20]; delete [20] arr;
然而,关于这一切的可悲部分是,没有符合标准的方法来检索通过尺寸供您自己使用: – /
确实,数组不包含数组的大小,您必须存储该信息以供日后使用。 通过delete
或free
删除数组时,它是指向您传递的已分配内存的指针。 使用的内存管理器(由系统或您自己的自定义覆盖new和delete)知道释放的内存区域,并跟踪它。 希望它有意义。
对,是真的。 这是为什么你应该很少直接尝试处理这个问题的一部分,而是使用标准容器。 关于处理它的唯一时间是你自己决定实现容器(在这种情况下,你通常会跟踪容器实现中的大小信息)。