-2

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
    Sorry but the way to detect deleted pointers is to write better quality code in the first place. There is no way that given a pointer you can tell from that pointer alone whether it has been deleted or not. – john Jul 31 '22 at 06:47
  • If you are designing a game engine then stop using unecessary "new" calls, that is the first step in avoiding memory leaks. Native types just use them as is, more complex types can be stored in STL collections, and if you need polymorphism (or more hands on memoery allocation) use std::make_unique or std::make_shared. In any case try to follow these guidelines : https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines. And don't optimize prematurely, always measure where your bottlenecks are and tackly them in order. – Pepijn Kramer Jul 31 '22 at 06:48
  • Your theory [does not work](https://onlinegdb.com/5TWsRKk5n) with g++. But it seems you are right VS modifies the deleted pointer to a given value, it does this even on a release build. I'm surprised, but this is NOT standard C++ behaviour, so you need to consult MS documentation. – john Jul 31 '22 at 06:59
  • And of course it must be said that delete can only modify one copy of the deleted pointer. If you have the same pointer value in a different variable that will still point to the deleted memory. – john Jul 31 '22 at 07:01

2 Answers2

3

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
...
Something Something
  • 3,999
  • 1
  • 6
  • 21
1

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...
Dani
  • 14,639
  • 11
  • 62
  • 110