0

In the following code, I expect the memory that pointer tr points, to be destroyed. However even though I verified sp1, points to the same address with tr, and clearing the set causes the trial object sp kept to be destroyed, tr still points to the same address and the trial object it shows is not destroyed, according to gdb, at the line return 0.

class trial
:public enable_shared_from_this<trial>
{
public:
    trial(int n)
    {
        cout<<"new trial created with number : " << n << endl;
        a = (int*)malloc(4);
        *a = n;
    }


    ~trial() {
        cout << "trial destroyed"<< endl;
    }

    int *a;
};

int main() {
    cout << "Program Started" << endl;

    trial *tr = new trial(5);
    shared_ptr<trial> sp1(tr);
    set<shared_ptr<trial>> trialVector;

    trialVector.insert(std::move(sp1));


    trialVector.clear();

    return 0;
}

When the program arrives to the line of return 0, console shows this :

Program Started
new trial created with number : 5
trial destroyed

acknowledging that, tr is indeed destroyed, once sp1 is removed from the set. But tr has still the same address and the same value.

What is going on here?

Edit: For clarity, my question is this:

Shouldn't the content of the address the pointer tr shows should be erased, once the last shared_ptr pointing to the manager object which points to the adress of pointer tr , is destructed upon being erased from the set ?

Ozum Safa
  • 1,458
  • 2
  • 15
  • 27
  • 1
    I don't understand what is the question exactly? it's seems ok. – David Haim Jun 21 '15 at 13:40
  • 1
    How can you determine that the "object is not destroyed"? After the destructor ran, inspecting the guts of what's left at that memory address is essentially meaningless - the object is dead. – Mat Jun 21 '15 at 13:42
  • Because in the debugger, I can see that it shows the same address, and that address has still the same trial object with value 5 for a, in it. – Ozum Safa Jun 21 '15 at 13:45
  • 2
    `tr` is now a dangling pointer - as soon as you pass control over to a `shared_ptr` it's risky to rely on the original raw pointer remaining valid as the `shared_ptr` is now responsible for its lifetime. In short, it's undefined behaviour to dereference `tr` once the `shared_ptr` has been destroyed. – Jonathan Potter Jun 21 '15 at 13:47
  • That is exactly the point of my experiment. It is undefined but how? `tr` still indeed has the same trial object after all shared_ptr is destroyed, and the managed object is destroyed. – Ozum Safa Jun 21 '15 at 13:51
  • Meaning that if I add line `cout << *(tr->a);` before the line `return 0;` , it will print out 5. I was suspicios that the address changes once a shared_ptr is created with a pointer, but that is not the case. When sp1 is created, it points to the managed_object which points to the same address with pointer `tr`. – Ozum Safa Jun 21 '15 at 13:52
  • 1
    Undefined, meaning the C++ standard doesn't define what happens when you access unallocated memory. Anything can happen, including it still looking like a valid object. – Jonathan Potter Jun 21 '15 at 13:56
  • @OzumSafa [this analogy](http://stackoverflow.com/a/6445794/3422652) might help – Chris Drew Jun 21 '15 at 13:57
  • Why are you using malloc? – Ed Heal Jun 21 '15 at 15:30
  • No particular reason, just happened to do that there. – Ozum Safa Jun 21 '15 at 15:35

2 Answers2

0

After the object is destroyed tr becomes a dangling pointer or the pointer to released memory. Why would the value in tr change if it is just a separate variable which happens to hold address to some point in memory?

riodoro1
  • 1,246
  • 7
  • 14
  • The value that the address has is not changed. Of course tr is going to show the same address, but that address still has the same `trial` object in it. According to gdb, paused at line `return 0`, it is. – Ozum Safa Jun 21 '15 at 13:50
  • 1
    Deallocation does not mean that the memory somewhere is wiped out, the object of class `trial` is still there, but the OS has marked the memory as free. If You were to create a `new trial` now, probably malloc would choose this spot for allocation, and the content of memory would change. This is why You always have to init a variable, as simply allocating it will make the variable hold data perviously in memory. As to why gdb can access this memory location, this spot, even when marked as free, still belongs to Your application. – riodoro1 Jun 21 '15 at 13:52
  • I hear you. That actually was great info. I think i figured out my confusion after i removed inheritence of `public enable_shared_from_this`. Once i did that, there was still trial object in the memory, but the integer pointer as nullified. That was the reaction i was expecting. Because deleting an integer pointer, makes the value 0, back to default. Now that I deleted the memory point to a trial object, it acted, probably in an undefined way, getting memory back to a default trial object state. – Ozum Safa Jun 21 '15 at 14:03
0

If you try following debug code it will be evident that shared_ptr sp1 has reference count is zero after std::vector::clear() call.

trialVector.clear();
std::cout<<sp1.use_count();
Steephen
  • 14,645
  • 7
  • 40
  • 47