请考虑以下代码:
int main()
{
int *intArPtr = new int[100];
int *intArPtr1 = intArPtr + 1;
delete [] intArPtr; //ok
//delete intArPtr; //valgrind warning, but no leaks!
//delete intArPtr1; //invalid pointer error
return 0;
}
我知道delete [] intArPtr
是删除此数组的唯一有效方法,但我只是对以下内容感到好奇:
delete intArPtr
不会产生任何内存泄漏?是吗
未定义的行为,我很幸运,没有任何行为?delete intArPtr1
在运行时出错?为什么它不删除所有元素,而是首先从数组中删除?答案 0 :(得分:12)
- 为什么
醇>delete intArPtr
不会产生任何内存泄漏?是吗 未定义的行为,我很幸运没有?
正确,在分配有delete
的内存上调用new[]
是未定义的行为。首先,它不会调用阵列成员上的析构函数。
对于两个人来说,即使您只是询问内存释放而不是关于对象破坏,delete
和delete[]
也可以相同地实现,或者它们可以不同。他们读起来就像他们一样,但他们不是:delete
和delete[]
是两个不同的运算符,可能有不同的实现。他们可以使用不同的分配策略(参见下面问题#3的答案)。
- 为什么
醇>delete intArPtr1
在运行时出错?为什么它不删除所有元素,而是首先从数组中删除?
您必须传递delete
分配有new
的指针。确切的指针。不是new
分配的内存区域内的指针,它不起作用。它必须是指向该区域起点的相同指针。
- C ++的运行时如何知道已分配数组的大小(对于delete [])?它存放在某个地方吗?
醇>
公共分配器策略是存储分配区域之前分配的字节数。然后delete
将获取您传递它的指针,向左看4或8个字节,并将该整数解释为该区域的大小。如果你传递一个指向其他地方的指针,它的回顾策略就会失败。
C ++语言没有指定如何跟踪内存分配,因此这是一个实现细节。不同的标准库,编译器和操作系统将以不同方式执行此操作。我所描述的只是一种可能的机制。
进一步阅读:
答案 1 :(得分:0)
是和否同时。使用delete
代替delete[]
并不干净,但通常有效。基本上,指针和偏移量都在分配时存储。这允许在使用delete
时进行适当的释放,即使偶然也是如此。
intArPtr1
与分配区域的指针不对应。尝试delete
时,运行时无法在分配表中找到此地址。
它存储在分配表中,指针指向已分配的区域。
答案 2 :(得分:-2)
数目: