Any creative ways to detect deleted data allocated in heap?

200 views Asked by At

I am designing a game engine and a lot of subsystems would interface with each other better if deleted pointers could be detected. I decided to take a look at what the actual memory address points to. It appears to point to 0000000000008123 in my PC. I wonder, does it points to the same memory address to anyone else. If it does, would it point to the same memory address in other operating systems? It most likely varies from PC to PC, but maybe storing what that actual value is at the beginning of the program could be helpful to detect deleted memory. Could this be a trustworthy method to detect deleted memory in C++? Here is the test case I used:

#include <iostream>

using namespace std;

int main() {
    cout << "Program operating..." << endl;

    for (unsigned int i = 0; i < 5; i++) {
        int* integer1 = nullptr;
        int* integer2 = nullptr;
        int* integer3 = nullptr;
        int* integer4 = nullptr;
        int* integer5 = nullptr;
        
        integer1 = new int(1);
        integer2 = new int(2);
        integer3 = new int(3);
        integer4 = new int(4);
        integer5 = new int(5);

        cout << integer1 << endl;
        cout << integer2 << endl;
        cout << integer3 << endl;
        cout << integer4 << endl;
        cout << integer5 << endl;
        cout << endl;

        delete integer1;
        delete integer2;
        delete integer3;
        delete integer4;
        delete integer5;

        cout << integer1 << endl;
        cout << integer2 << endl;
        cout << integer3 << endl;
        cout << integer4 << endl;
        cout << integer5 << endl;
        cout << endl;
    }

    cout << "Program terminated..." << endl;
}

Output

0000000000008123
0000000000008123
0000000000008123
0000000000008123
0000000000008123
2

There are 2 answers

0
Henrique Bucher On BEST ANSWER

Smart pointers do exactly what you are looking for with the advantage that they will reclaim memory as objects go out of scope.

You can query them to check if they are empty or not.

Example: https://godbolt.org/z/6s5vxrjsa

#include <iostream>
#include <memory>
int main() {
    std::cout << "Program operating..." << std::endl;
    for (unsigned int i = 0; i < 5; i++) {
        std::unique_ptr<int> integer1( new int(1));
        std::cout <<  integer1.get() << " empty:" << (integer1?"No":"Yes") << std::endl;        
        integer1.reset();
        std::cout <<  integer1.get() << " empty:" << (integer1?"No":"Yes") << std::endl;        
    }
    std::cout << "Program terminated..." << std::endl;
}
Program operating...
0x602000000010 empty:No
0 empty:Yes
0x602000000030 empty:No
0 empty:Yes
0x602000000050 empty:No
0 empty:Yes
0x602000000070 empty:No
0 empty:Yes
0x602000000090 empty:No
0 empty:Yes
Program terminated...

Note that you do not need to delete the object. They will be deleted automatically. This example shows this:

#include <iostream>
#include <memory>
struct Printer {
    Printer( int value ) : _value(value) { std::cout << "Creating printer with value " << value << std::endl; }
    ~Printer() { std::cout << "Deleting printer with value " << _value << std::endl; }
    int _value;    
};
int main() {
    std::cout << "Program operating..." << std::endl;
    for (unsigned int i = 0; i < 5; i++) {
        std::unique_ptr<Printer> printer( new Printer(2*i));
        std::cout <<  printer.get() << " empty:" << (printer?"No":"Yes") << std::endl;        
        printer.reset();
        std::cout <<  printer.get() << " empty:" << (printer?"No":"Yes") << std::endl;   
        printer.reset( new Printer(2*i+1) );     
        std::cout <<  printer.get() << " empty:" << (printer?"No":"Yes") << std::endl;   
    }
    std::cout << "Program terminated..." << std::endl;
}
Program operating...
Creating printer with value 0
0x602000000010 empty:No
Deleting printer with value 0
0 empty:Yes
Creating printer with value 1
0x602000000030 empty:No
Deleting printer with value 1
Creating printer with value 2
0x602000000050 empty:No
Deleting printer with value 2
0 empty:Yes
Creating printer with value 3
0x602000000070 empty:No
Deleting printer with value 3
...
0
Dani On

Although tested on my own pc yields the same address, you can't assume this for any system that run c++

This is the output on Linux machine:

> Program operating...
0x55650b474280
0x55650b4742a0
0x55650b4742c0
0x55650b4742e0
0x55650b474300

0x55650b474280
0x55650b4742a0
0x55650b4742c0
0x55650b4742e0
0x55650b474300

0x55650b474300
0x55650b4742e0
0x55650b4742c0
0x55650b4742a0
0x55650b474280

0x55650b474300
0x55650b4742e0
0x55650b4742c0
0x55650b4742a0
0x55650b474280

0x55650b474280
0x55650b4742a0
0x55650b4742c0
0x55650b4742e0
0x55650b474300

0x55650b474280
0x55650b4742a0
0x55650b4742c0
0x55650b4742e0
0x55650b474300

0x55650b474300
0x55650b4742e0
0x55650b4742c0
0x55650b4742a0
0x55650b474280

0x55650b474300
0x55650b4742e0
0x55650b4742c0
0x55650b4742a0
0x55650b474280

0x55650b474280
0x55650b4742a0
0x55650b4742c0
0x55650b4742e0
0x55650b474300

0x55650b474280
0x55650b4742a0
0x55650b4742c0
0x55650b4742e0
0x55650b474300

Program terminated...