1
#include <list>
#include <iostream>

struct Foo
{
    Foo(int a):m_a(a)
    {}
    ~Foo()
    {
        std::cout << "Foo destructor" << std::endl;
    }
    int m_a;
};

int main( )
{
   std::list<Foo> a;
   Foo b(10);
   std::cout << &b << std::endl;
   a.push_back(b);
   Foo* c = &(*a.begin());
   std::cout << c << std::endl;
   a.erase(a.begin());
   std::cout << a.size() << std::endl;
   c->m_a = 20;
   std::cout << c->m_a << std::endl;
   std::cout << b.m_a << std::endl;
}

結果は次のとおりです。

0x7fff9920ee70
0x1036020
Foo destructor
0
20
10
Foo destructor

私は通常、リスト内のオブジェクトを消去した後、thar オブジェクトのメンバー変数にアクセスできなくなると考えています。しかし、上記では、何を指してc->m_aいるオブジェクトを消去した後でもアクセスできます。なぜですか?c

4

3 に答える 3

2

意図的Foo* c = &(*a.begin());に破棄するオブジェクトへのポインタを作成しました ( 経由erase())。ただし、オブジェクトのメモリはまだそこにあります (これは非常に単純なアプリケーションであり、OS は他の目的でそれを要求しなかったためです)。

したがって、もう使用する必要のないメモリを効果的に使用できます。

于 2014-02-18T13:03:19.887 に答える
0

まあ、データの整合性は、メモリのその部分を割り当てた場合にのみ保証されます (スタック上または new/malloc を使用したヒープ上で)。

データを解放するとどうなるかは未定義です (つまり、実装に依存します)。メモリを解放する最も効率的な方法は、単にメモリを使用可能としてマークし、別のプログラムが malloc を使用してそのメモリの一部を要求して上書きするまでデータをそこに残しておくことです。これは、ほとんどの実装がこれを処理する方法です。

C++ は、読み書きしているデータがプログラムに属しているかどうかをチェックしません。そのため、プログラムがアクセスできないメモリ内の場所にデータを書き込もうとすると、セグメンテーション違反が発生します。

あなたの場合、メモリを解放し、すぐにその値を確認します。C++ は喜んでコードを実行します。最近解放したばかりなので、データがまだそこにある可能性は非常に高いです (ただし、確実ではありません: 遅かれ早かれ上書きされます)。

于 2014-02-18T13:08:55.823 に答える