在动态对象数组上调用delete []不会释放内存?

时间:2012-10-07 19:59:22

标签: c++ memory-management dynamic-allocation

在以下代码中:

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?
  2. ,那么如何存在索引号为15的元素
  3. 为什么指针在取消分配整个数组后仍然有值?
  4. 我尝试使用单一分配删除:

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

    结果是正常的:

    5        
    0        
    

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

3 个答案:

答案 0 :(得分:9)

  1. 存在超出预期大小的元素,因为那里的内存恰好存在。对它采取任何行动是非法的,并导致黑暗未知。

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

答案 1 :(得分:1)

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

大多数情况下,您会遇到分段错误,因为您访问其他应用程序的内存。这一次,你只是'幸运'。或者我称之为“不吉利”,因为您无法立即告知执行程序您的程序存在内存错误。

答案 2 :(得分:1)

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