Why access deleted pointer won’t crash the program?

#include <iostream>
#include<list>

using namespace std;
template <class T>
class Ptr {
public:
    Ptr() {
        a = nullptr;
        l.push_back(0);
    }

std::list<int> l;
void print_this() {
    cout<<this<<endl;
}

protected:
    int *a;
};

int main()
{
    Ptr<int> *ptr = new Ptr<int>();
    delete ptr;
    //ptr = nullptr; //if uncomment this line will crash
    auto p = &(ptr->l);  
    cout<<"p is "<<p<<endl;
    ptr->print_this();
    ptr->l.push_back(1);
    cout<<"size is "<<ptr->l.size()<<endl;
    cout<<"end";
    return 0;
}

I run code here: https://www.programiz.com/cpp-programming/online-compiler/ output is :

p is 0x5628eb47deb0
0x5628eb47deb0
size is 2
end

if I set ptr to nullptr after delete, it will crash at push_back. But still fine when I access the list.

How is it even possible that I push data to a dangling pointer without crashing it??

Answer

When you have a pointer to a class, and call a non-virtual function on it, whatever the address is at the pointer will be considered the this pointer. Even if it is zero. As long as you don’t try to access members at that address, you should have no problem printing the this poniter.

struct A {
    void printThis() {
        printf("%dn", this);
    }
};

    int _tmain(int argc, _TCHAR* argv[])
    {
        A * a = (A*) 777;
        a->printThis(); // will print 777
    
        a = NULL;
        a->printThis(); // will print 0
    
        return 0;
    }

When you delete a pointer and don’t set its address to null, the previous address value is kept.

Accessing a deleted pointer is undefined behavior. It is not required to crash. It just may be that the random data that you are pointing to has some meaning somewhere else in the program. It may even be your old data. Deleting a pointer tells the system it can reuse that memory, but it may not have had time to reuse it yet, and so the old data could still be visible.

Finally your program crashes when you uncomment your line because that sets ptr = 0, and &(0x0000000->l) is an invalid memory reference.