例如:
int *a, *b;
a = new int[10];
b = new int(12);
b = a; // I know there's memory leak, but let's ignore it first
delete [] b; // line L
会发生什么?是否会删除整个数组成功?
如果 L 行被替换为: b = a + 1; 删除[] b;
或者通过这个: 一个++; 删除[]一个;
最后,如果动态数组的长度与起始地址相关联,或者换句话说,与数组本身相关联,我们是否有任何方法可以在不使用另一个变量来存储它的情况下获取它的长度长度?
非常感谢!
最佳答案
内存块大小和数组长度信息与对象的地址相关联,即数组第一项的地址。
即您的 delete[]
在给定代码中是安全的
int *a, *b;
a = new int[10];
b = new int(12);
b = a; // I know there's memory leak, but let's ignore it first
delete [] b; // line L
但是,没有可移植的方法来1访问相关信息。这是一个实现细节。如果您需要此类信息,请使用 std::vector
。
要了解无法访问信息的原因,请首先注意释放所需的内存块大小可能大于数组长度乘以数组项的大小。所以我们在这里处理两个不同的值。对于 POD 项类型的数组,不需要项析构函数调用,因此不需要显式存储数组长度值。
即使对于需要析构函数调用的数组,也不需要显式存储与数组关联的数组长度值。例如,在模式代码中 p = new int[n];任何(); delete[] p;
,编译器原则上可以选择将数组长度放在一些不相关的地方,这样它可以很容易地被为 delete
表达式生成的代码访问。例如。它可以放在处理器寄存器中。
根据编译器的智能程度,也不一定需要显式存储内存块大小。例如,编译器可以注意到在某些函数 f
中,分配了三个数组 a
、b
和 c
,它们的大小在第一次分配时已知,最后三个都被释放。因此,编译器可以将三个分配替换为一个,同上将三个释放替换为一个(2C++14 §5.3.4/10 明确允许此优化)。
<支持>
1 除了在 C++14 及更高版本中的释放函数中,这有点晚了。
2 C++14 §5.3.4/10:“允许实现省略对可替换全局分配函数的调用(18.6.1.1、18.6.1.2)。
当它这样做时,存储由实现提供或通过扩展
分配另一个新表达式。该实现可以扩展 new-expression e1
的分配
为 new-expression e2
if …提供存储空间”
关于c++ - C++中动态数组的长度信息是关联指针还是首元素地址?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36371825/