考虑以下代码:
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
会在运行时出错?为什么它不删除所有元素,而是首先从数组中删除? - C++ 的运行时如何知道分配数组的大小(对于 delete [])?它存储在某个地方吗?
最佳答案
- Why
delete intArPtr
doesn't yield any memory leaks? Is it undefined behavior and I'm just lucky no to have any?
正确,在用 new[]
分配的内存上调用 delete
是未定义的行为。其一,它不会调用数组成员的析构函数。
对于两个,即使您只是询问内存释放而不是对象销毁,delete
和 delete[]
也有可能以相同的方式实现,或者他们是不同的。它们读起来好像它们是相同的东西,但它们不是:delete
和 delete[]
是两个不同的运算符,具有可能不同的实现。他们可以使用不同的分配策略(请参阅下面问题 #3 的答案)。
- Why
delete intArPtr1
gives an error on run-time? Why doesn't it delete all elements but first from the array?
您必须向 delete
传递一个分配有 new
的指针。确切的指针。不是 new
分配的内存区域中的指针,这是行不通的。它必须是指向区域开始的相同指针。
- How does C++'s runtime knows size of the allocated array (for delete [])? Is it stored somewhere?
一个常见的分配器策略是在分配区域之前存储分配的字节数。 delete
然后会获取您传递给它的指针,向左查找 4 或 8 个字节,并将该整数解释为该区域的大小。如果您将指向其他地方的指针传递给它,它的回溯策略就会失败。
C++ 语言没有指定如何跟踪内存分配,因此这是一个实现细节。不同的标准库、编译器和操作系统会以不同的方式执行此操作。我所描述的只是一种可能的机制。
进一步阅读:
关于c++ - 为什么我不能通过指针从数组中删除非第一个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32875930/