繁体   English   中英

为什么无法访问新[]'d数组的大小?

[英]Why is it not possible to access the size of a new[]'d array?

使用new []分配数组时,为什么不能从指针中找出该数组的大小? 它必须在运行时知道,否则delete []不知道要释放多少内存。

除非我错过了什么?

在典型的实现中,动态内存块的大小以某种方式存储在块本身中 - 这是真的。 但是没有标准的方法来访问这些信息。 (实现可以提供特定于实现的访问方式)。 这就是malloc/free ,这就是new[]/delete[]

实际上,在一个典型的实现中, new[]/delete[]调用的原始内存分配最终由一些特定于实现的malloc/free -like对处理,这意味着delete[]实际上并不需要关心多少要取消分配的内存:它只是调用内部free (或任何名称)来处理它。

delete[]确实需要知道的是在数组元素类型具有非平凡的析构函数的情况下要破坏多少元素。 这就是你的问题 - 数组元素的数量 ,而不是块的大小(这两个不一样,块可能比数组本身真正需要的大)。 出于这个原因,数组中元素的数量通常也通过new[]存储在块内,然后由delete[]检索以执行正确的数组元素销毁。 也没有标准方法来访问此号码。

(这意味着在一般情况下,一个典型的存储器块由分配new[]将独立地,同时地同时存储以字节为单位的物理块大小阵列元素计数这些值由不同级别的C ++内存分配机制存储-原始内存allocator和new[]本身 - 并且不以任何方式相互交互)。

但是,请注意,由于上述原因,数组元素计数通常仅在数组元素类型具有非平凡的析构函数时存储。 即这个数量并不总是存在。 这是为什么提供访问数据的标准方法不可行的原因之一:您必须始终存储它(浪费内存)或通过析构函数类型限制其可用性(这令人困惑)。

为了说明上述内容,在创建int数组时

int *array = new int[100];

数组的大小(即100 )通常不会new[]存储,因为delete[]不关心它( int没有析构函数)。 块的物理大小(以400字节或更多)通常由原始内存分配器存储在块中(并由delete[]调用的原始内存释放器使用),但它很容易变成420出于某些特定于实现的原因。 所以,这个大小对你来说基本没用,因为你将无法从中获得精确的原始数组大小。

您最有可能访问它,但它需要您对分配器的深入了解,并且不可移植。 C ++标准没有规定实现如何存储这些数据,因此没有一致的方法来获取它。 我认为它没有具体说明,因为不同的分配器可能希望以不同的方式存储它以提高效率。

这是有道理的,例如,分配的块的大小可能不一定与阵列的大小相同。 虽然它是真实的是new[]可以存储元件的数量(呼叫每个元件的析构函数),它不具有作为它不会被需要用于空析构函数。 还没有标准方法( C ++ FAQ Lite 1C ++ FAQ Lite 2 )实现new[]存储数组长度的方法,因为每种方法都有其优缺点。

换句话说,它通过不指定任何有关实现的内容,允许尽可能快地分配。 (如果实现必须每次都存储数组的大小以及分配的块的大小,则会浪费您可能不需要的内存)。

简而言之,C ++标准不需要支持。 如果你对编译器的内部结构有足够的了解,你可以弄清楚如何访问这些信息,但这通常被认为是不好的做法。 请注意,堆分配的数组和堆栈分配的数组的内存布局可能存在差异。

请记住,你在这里谈论的本质上也是C风格的数组 - 即使newdelete是C ++运算符 - 并且行为是从C继承的。如果你想要一个大小合适的C ++“数组”,你应该使用STL(例如std :: vector,std :: deque)。

暂无
暂无

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

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