Thursday 30 June 2016

c++ - What does Visual Studio do with a deleted pointer and why?




A C++ book I have been reading states that when a pointer is deleted using the delete operator the memory at the location it is pointing to is "freed" and it can be overwritten. It also states that the pointer will continue to point to the same location until it is reassigned or set to NULL.



In Visual Studio 2012 however; this doesn't seem to be the case!



Example:



#include 

using namespace std;


int main()
{
int* ptr = new int;
cout << "ptr = " << ptr << endl;
delete ptr;
cout << "ptr = " << ptr << endl;

system("pause");

return 0;

}


When I compile and run this program I get the following output:



ptr = 0050BC10
ptr = 00008123
Press any key to continue....






Clearly the address that the pointer is pointing to changes when delete is called!



Why is this happening? Does this have something to do with Visual Studio specifically?



And if delete can change the address it is pointing to anyways, why wouldn't delete automatically set the pointer to NULL instead of some random address?


Answer



I noticed that the address stored in ptr was always being overwritten with 00008123...




This seemed odd, so I did a little digging and found this Microsoft blog post containing a section discussing "Automated pointer sanitization when deleting C++ objects".




...checks for NULL are a common code construct meaning that an existing check for NULL combined with using NULL as a sanitization value could fortuitously hide a genuine memory safety issue whose root cause really does needs addressing.



For this reason we have chosen 0x8123 as a sanitization value – from an operating system perspective this is in the same memory page as the zero address (NULL), but an access violation at 0x8123 will better stand out to the developer as needing more detailed attention.




Not only does it explain what Visual Studio does with the pointer after it is deleted, it also answers why they chose NOT to set it to NULL automatically!







This "feature" is enabled as part of the "SDL checks" setting. To enable/disable it go to: PROJECT -> Properties -> Configuration Properties -> C/C++ -> General -> SDL checks



To confirm this:



Changing this setting and rerunning the same code produces the following output:



ptr = 007CBC10
ptr = 007CBC10






"feature" is in quotes because in a case where you have two pointers to the same location, calling delete will only sanitize ONE of them. The other one will be left pointing to the invalid location...


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...