2

在以下代码中:

int main(int argc,char * argv[]){
  int * ptr;
  ptr = 0; // tried also with NULL , nothing changes
  ptr = new int[10]; // allocating 10 integers
  ptr[2] = 5;
  ptr[15] = 15;  // this should cause error (seg fault) - but it doesn't

  cout << ptr[2] << endl;
  cout << ptr[15] << endl;  // no error here

  delete [] ptr;

  cout << ptr[2] << endl;   // prints the value 5
  cout << ptr[15] << endl;  // prints the value 15
}

执行的结果是:

5        
15        
5        
15        
  1. 如果我只分配 10,索引号为 15 的元素怎么可能存在?
  2. 为什么整个数组被释放后指针仍然有值?

我尝试使用这样的单一分配删除:

int * ptr;
ptr = 0;
ptr = new int;
*ptr = 5;
cout << *ptr << endl;
delete ptr ;
cout << *ptr << endl;

结果正常:

5        
0        

在 fedora 17 和另一个平台(SLC5 - red hat based linux)上使用 gcc 4.7.2 和 gcc 4.1.2 进行了测试,以确保它不依赖于编译器。我在这里做错了什么?

4

3 回答 3

9
  1. 超出数组预期大小的元素存在,因为那里的内存恰好存在。用它做任何事情都是非法的,会导致黑暗的未知。

  2. 释放意味着不再为您分配内存。这并不意味着有人去那里清理它。但是访问你剩下的东西是非法的,并且会导致黑暗的未知。

于 2012-10-07T20:02:25.040 回答
1

您正在访问不属于该数组的内存。它的工作原理是纯粹的运气。如果程序没有崩溃,则意味着您正在覆盖属于您自己的应用程序的部分内存,因此您在某处破坏了某些东西,并且无法再保证您的程序正常运行。

大多数情况下,您会遇到分段错误,因为您访问了其他应用程序的内存。这一次,你只是“幸运”。或者正如我所说的“不幸”,因为您无法立即从执行中判断您的程序存在内存错误。

于 2012-10-07T20:02:33.030 回答
1

取消引用已删除的指针是 C++ 标准定义的未定义行为。这就是未定义的行为。你可能会崩溃,你可能会得到 0,你可能会得到以前的东西,或者 42。根据定义,此时没有“正常”行为。

于 2012-10-07T20:06:10.860 回答