Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What determines what is written to a C++ pointer when delete is called?

I have a pointer to a given class. Lets say, for example, the pointer is:

0x24083094

That pointer points to:

0x03ac9184

Which is the virtual function table of my class. That makes sense to me. In windbg, everything looks correct.

I delete said pointer. Now at 0x24083094 is:

0x604751f8

But it isn't some random garbage, that address is put in there every time, it is consistently 0x604751f8! So much so that I can actually use that address to determine if that pointer was deleted, between executions of my application!

But Why? How does it determine that 0x604751f8 should be written there?

For the record, I am using windows, building under visual studio 2003.

I know I can't rely on that value being set, even if it does appear to be consistent, but can I rely on it being different? I.e., 0x03ac9184 will not be at 0x24083094 if the pointer is deleted, right? What is put there? It Could be anything, but 0x03ac9184 will definitely not be there (or else I could still call methods, since that is the virtual function table). Am I right?

I feel like I have answer. can't rely on anything after it is deleted. Maybe some background will help people see where I am coming from. Essentially, I am trying to fix a bug where a pointer gets deleted out from under me. It's a long story, I won't go into the details.

Basically, I am trying to detect that I am in this situation, so I can exit gracefully from my function. I suppose the easiest and best way is to just figure out who actually owns this pointer, and ask him if anything has changed. So I am going to implement a fix like that. It avoids any of this C++ delete hacker-y I was discussing.

However, the interesting thing is that in our code we have a class called 'BogusObject' that essentially acts as a tray catching people that accidentally dereference freed objects. Basically, we hook our own delete functions and bash the BogusObject class into the vtable of any freed class.

Then if someone calls something they get a nice message saying something to the effect of "hey, something is wrong dude.". This is happening in my case. I.e., 0x604751f8+(someoffset) is inside the BogusObject class. But we no longer use BogusObject! It literally isn't set up anywhere (even links properly if I completely remove the BogusObject class), and yet I still end up getting the nice message saying something is wrong! But I am now of the opinion that it is a coincidence.

For some reason the runtime is putting that 0x604751f8 value in this pointer when it is deleted, and that just happens to correspond with the one class that has a purpose to catch situations like this!

like image 959
pj4533 Avatar asked May 07 '09 17:05

pj4533


2 Answers

Nothing in the standard determines what gets written there. Visual studio (at least in debug mode) will often write sentinal values all over the place to help in catching bugs early.

This value is not something you can rely on, but if you ever find that value popping up in your program mysteriously, you can assume that somewhere you are referencing deleted memory. See this answer for a list of values under one compiler.

It's also entirely possible that it's a free list pointer, pointing to the next piece of free memory. Most memory allocators keep their free memory in a linked list of sorts, using the free memory they are tracking to store the tracking data.

In any case, you MUST NOT use that pointer value for anything you want to keep working, unless you call up microsoft and get some documentation saying why that value is what it is, and get them to guarantee that it will not change. And even then, know that your code is now tied to one compiler's behaviour. In C++, accessing unallocated memory is undefined and evil.

Edit: You can't even rely on that value changing after a delete. There's nothing that says a compiler needs to modify the data on delete.

like image 153
Eclipse Avatar answered Sep 20 '22 15:09

Eclipse


One you delete an object the memory it was using gets put back into the free store (heap). Of course the free store will have its own data structures (and possibly debugging data) that it will apply to that memory.

What the particular value you're looking at means? Could be almost anything.

like image 36
Michael Burr Avatar answered Sep 18 '22 15:09

Michael Burr