Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
284 views
in Technique[技术] by (71.8m points)

c++ - Why I can access member functions even after the object was deleted?

I'm new to C++ and from what I learned so far when you call delete on a pointer that points to something created on the heap then whatever is pointed by that pointer gets erased and the memory is freed, right?

However when I tried this on a simple class:

class MyClass
{
    int _Id;
public:
    MyClass(int id) : _Id(id)
    {
        std::cout << "$Constructing the damn thing! " << _Id << std::endl;
    }
    ~MyClass()
    {
        std::cout << "?Destructing the damn thing! " << _Id << std::endl;
    }
    void Go_XXX_Your_Self()
    {
        std::cout << "%OooooooooO NOOOOOO! " << _Id << std::endl;
        delete this;
    }
    void Identify_Your_Self()
    {
        std::cout << "#Object number: " << _Id << " Located at: " << this << std::endl;
    }
};

These are just some stupid tests to see how delete works:

int main()
{
    MyClass* MC1 = new MyClass(100);
    MyClass* MC2 = new MyClass(200);
    MyClass* MC3 = MC2;

    std::cout << MC1 << " " << MC2 << " " << MC3 << " " << std::endl;

    MC1->Identify_Your_Self();
    MC2->Identify_Your_Self();
    MC3->Identify_Your_Self();

    delete MC1;

    MC1->Identify_Your_Self();


    MC3->Go_XXX_Your_Self();

    MC3->Identify_Your_Self();


    delete MC2;

    MC2->Identify_Your_Self();

    MC2->Go_XXX_Your_Self();

    MC2->Identify_Your_Self();

    return 0;
}

Here's the output:

$Constructing the damn thing! 100
$Constructing the damn thing! 200
0x3e3e90 0x3e3eb0 0x3e3eb0
#Object number: 100 Located at: 0x3e3e90
#Object number: 200 Located at: 0x3e3eb0
#Object number: 200 Located at: 0x3e3eb0
?Destructing the damn thing! 100
#Object number: 0 Located at: 0x3e3e90
%OooooooooO NOOOOOO! 200
?Destructing the damn thing! 200
#Object number: 4079248 Located at: 0x3e3eb0
?Destructing the damn thing! 4079248
#Object number: 4079280 Located at: 0x3e3eb0
%OooooooooO NOOOOOO! 4079280
?Destructing the damn thing! 4079280
#Object number: 4079280 Located at: 0x3e3eb0

So, my question is, why I'm still able to call Go_XXX_Your_Self() and Identify_Your_Self() even after the object was deleted?

Is this how it works in C++? (is there even after you delete it?)

Also can you check to see if it's not there? (I know theoretically is not possible but I'm curious to see what methods are out there)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

So, my question is, why I'm still able to call Go_XXX_Your_Self() and Identify_Your_Self() even after the object was deleted?

Because of undefined behavior.

Is this how it works in C++? (is there even after you delete it?)

Because of undefined behavior. There is no guarantee that it will work the same on other implementations. Again, undefined behavior.

Also can you check to see if it's not there? (I know theoretically is not possible but I'm curious to see what methods are out there)

delete MC1;
MC1 = nullptr;

By setting the pointer to nullptr after deleteing it, the runtime is most likely to detect that you are accessing an invalid, you-have-no-right-to-use location. Also, by diligently doing this for all applicable pointers, you have the ability to check if the object is valid or not (valid if non-nullptr).

if(my_ptr) {
   // my_ptr is most possibly valid (though you can still go wrong)
   // use my_ptr
}

Similarly, you should also set raw pointers to nullptr when they aren't yet initialized to some valid address.

MyClass* some_ptr = nullptr;
...

But again, if you have access to modern C++11 facilities, it's much better not to use raw pointers at all, and just use std::unique_ptr or std::shared_ptr (depending on your required semantics). And on future C++ standard revisions, you may also want to use the proposed std::exempt_ptr which is a non-owning, observe-only pointer wrapper.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...