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;
}

The result is:

0x7fff9920ee70
0x1036020
Foo destructor
0
20
10
Foo destructor

I usually think after i erase an object in a list i can't access member variable of thar object any more. But in the above I can still access c->m_a after I have erased the object what c points to,Why?

Thinking
  • 13
  • 2

3 Answers3

2

with Foo* c = &(*a.begin()); you have created a pointer to an object which you intentionally destroy (via the erase()). However the memory for the object for is still there (since this is a very simple application, and the OS did not claim it for something else).

So you effectively use memory which is not yours anymore to use.

Ferenc Deak
  • 34,348
  • 17
  • 99
  • 167
0

Well, data integrity is only guaranteed as long as you have allocated that part of the memory (whether by it on the stack or on the heap using new/malloc).

What happens with your data once you have freed it, is undefined (meaning it is implementation dependent). The most efficient way of freeing memory is by simply marking the memory as being available, leaving your data there until another program claims that part of the memory using malloc and overwrites it. This is how most implementations will handle this.

C++ does not check whether the data you are reading or writing belongs to your program. That is why you get a segmentation fault when your program tries to write data to a place in the memory it does not have access to.

In your case you will free the memory and then you check for its value immediately. C++ will happily execute your code. Since you only freed it recently, the odds are very high that your data is still there (but certainly not guaranteed: sooner or later it will get overwritten).

bverhagen
  • 99
  • 4
0

Welcome to the wild world of pointers. What exactly you got here is case of Dangling Pointer (Read up the wiki article, it explains it in detail).

Basically what happened here is that after removing the item from the list, the pointer c became dangling pointer (it is pointer to a memory location which is no more occupied by Foo object). But still C++ will allow you to read/write through this pointer, but the side affects will be totally non deterministic (means anything can happen). As the code is simple s during testing your code you just got lucky (or unlucky as these type of problems can become very difficult and dangerous as they get old).

Ammar
  • 233
  • 1
  • 8