关于内存损坏的困惑c ++

时间:2014-04-17 06:13:09

标签: c++

class Test {
    int a ;
    int b ;

    public :
    Test() { }
    Test(int x , int y) : a(x),b(y) { }

    int getA() { return a ;}
    int getB() { return b ;}
};

int main () {
    list <Test *> mylist;
    Test *t1 = new Test(10,20);

    mylist.push_back(t1);
    delete t1 ;   //deleting the pointer

    list <Test*> ::iterator it ;

    for( it = mylist.begin() ; it != mylist.end() ; ++it ) {
        Test *temp = (*it) ;
        cout<<"taking data from list="<<temp->getB()<<endl;
    }
    return 0 ;
}

我对程序的输出感到困惑,在列表中插入指针后我删除了指针。理想情况下,它应该给出分段错误,但它打印0。

3 个答案:

答案 0 :(得分:2)

delete t1 ;   //deleting the pointer

这个delete s 不是指针,而是指向指针的对象。

push_backstd::list 指针,只复制指针,而不是真实对象。

处理此问题的两种标准方法是:

  • 如果确实需要在容器中存储指针,delete当您知道该对象时,list将不再使用
  • 避免此类问题的最常见方法是list <Test>而不是list <Test*>

答案 1 :(得分:0)

做的时候

delete t1 ;   //deleting the pointer

你要删除指针指向的对象,而不是指针本身(通过值复制到列表中)。

稍后取指针是完全有效的操作

Test *temp = (*it) ;

无效的是使用指向已删除内存的指针,导致未定义的行为

cout<<"taking data from list="<<temp->getB()<<endl;

这意味着您可能会获得访问冲突或垃圾值,甚至是旧值,具体取决于内存管理方式。

答案 2 :(得分:0)

调用delete t1,只需调用该对象的析构函数并释放内存。 指针的值不会改变。它只是内存地址的值。

因此您仍然可以访问t1指向的内存块。但行为尚未明确。

通过调试,您可能会收到无效数据。因为一些调试堆实现用字节模式填充释放的内存。在发布程序中,您可能会使旧值和程序接缝正常工作。