Sign in to follow this  
Xsy

Multiple pointers to the same object - deletion

Recommended Posts

Hey , I just want to clarify if what I presume is true. Given the following:
class Foo
{
  /......./
};

int main()
{
  Foo *p = new Foo();
  Foo *p1 = p;
  Foo *p2 = p;
  Foo *p3 = p;

  delete p;
}


I know that the delete operator actually deletes the object the pointer is pointing to , so what happens to the 3 other pointers pointing to the that object? Are they now pointing to NULL or to nothing at all? Now consider this example:

// FooList1.h
 vector<Foo*> FooList1;

// FooList2.h
 vector<Foo*> FooList2;


A pointer in FooList1 points to the same object that a pointer in FooList2 points to. If I empty one of the containers and delete all of it's pointers , does this mean that all of the pointers in the other container will become invalid and 'dangerous' to use because they will point to nothing? Lastly , a pointer that points to nothing , it has it's own address and memory location. Does the OS clean up pointers like that so it wont be considered as a memory leak?

Share this post


Link to post
Share on other sites
Quote:

so what happens to the 3 other pointers pointing to the that object? Are they now pointing to NULL or to nothing at all?

They're pointing to unallocated memory (effectively, to garbage).

Quote:

If I empty one of the containers and delete all of it's pointers , does this mean that all of the pointers in the other container will become invalid and 'dangerous' to use because they will point to nothing?

They will all point to unallocated memory, yes (not to "nothing").

Quote:

Lastly , a pointer that points to nothing , it has it's own address and memory location. Does the OS clean up pointers like that so it wont be considered as a memory leak?

A "pointer that points to nothing" is more commonly called the null pointer; it's not pointing to allocated memory so there is nothing to leak.

Your OS will typically, via one means or another, "release" the memory you may leak at the end of the program, but that's not something you should rely on, and does not prevent all issues.

Share this post


Link to post
Share on other sites
So in C or C++ it helps to not think of pointers as tethers to the objects to which they point. Pointers are just memory addresses where the object can be found. So if you call delete on a pointer, it just frees the memory at the address stored in the pointer. Other pointers with the same address are still pointing to the same place in memory where the object used to be, but that object just isn't there anymore.

It's like if I move and don't tell my friends. My old address is still a real address, I just don't live there anymore. So they're gonna be bummed when they drop by to say hi and some 80yr old WWII vet answers the door with a shotgun.

-me

Share this post


Link to post
Share on other sites
Thank's for the quick replies!
So to prevent errors with dangling pointers I just assign them to point to NULL , or otherwise just use a reference - counting smart pointer.

Share this post


Link to post
Share on other sites
Well, a "null" (well, null is apparently just a macro for 0) value for a pointer might be easier for you to manage, but you still have to make sure your code doesn't dereference it.

Share this post


Link to post
Share on other sites
Quote:
Original post by Xsy
Thank's for the quick replies!
So to prevent errors with dangling pointers I just assign them to point to NULL , or otherwise just use a reference - counting smart pointer.

Ideally, you will write your program so dangling references are impossible. In some cases, this will involve using smart pointers. In others, correctly scoping the variables might be sufficient.

NULL pointers should be reserved for things that are optional, by design. NULL is an extra corner case that the code has to manage, if you can write your programs such that your (smart) pointers always point to something valid then you can reduce the number of mistakes you can make.

In fact, to be clearer in intent you might use boost::optional<> rather than a nullable pointer to indicate where a value might be absent.

Share this post


Link to post
Share on other sites
Quote:
Original post by Xsy
Thank's for the quick replies!
So to prevent errors with dangling pointers I just assign them to point to NULL , or otherwise just use a reference - counting smart pointer.


Setting them to null or another invalid memory address (e.g. -1 or 0xDEADBEEF) is a good idea. This way, if you try to dereference them, you will get an instant access violation, which may save you tons of debugging time down the road. Note that dereferencing a regular dangling pointer may or may not crash; it can cause invisible random heap corruption; and it can pose a security risk.

Using "smart" pointers is generally a good idea, but they come with their own set of problems. Using a managed, garbage collected language is usually an even better idea (but I'm going to be flamed if I suggest this, so I won't). :) Of course, the best solution would be to use a language which cannot have dangling pointers / null references by design, like Ocaml - but suggesting that on gamedev would be akin to throwing petroleum into a raging fire...

Share this post


Link to post
Share on other sites
something like shared_ptr is very useful here, though you have to be careful when you copy the address out of a shared_ptr -- If you call delete on the normal pointer the shared_ptrs will dangle, and if all the shared pointer are deleted / go out of scope, the regular pointer will then dangle.

Also, and perhaps this was corrected in some of the interceding posts, but from your original post it appears as though you may be under the belief that calling delete on a pointer sets it to a safe value (eg NULL). This is not the case, after you call delete on a pointer, that same pointer still points to where the object was. That's why the idiom is to set a deleted pointer to NULL (or 0) immediately after calling delete on it.

Share this post


Link to post
Share on other sites
Quote:
Original post by Fiddler
Setting them to null or another invalid memory address (e.g. -1 or 0xDEADBEEF) is a good idea. This way, if you try to dereference them, you will get an instant access violation, which may save you tons of debugging time down the road. Note that dereferencing a regular dangling pointer may or may not crash; it can cause invisible random heap corruption; and it can pose a security risk.

Using "smart" pointers is generally a good idea, but they come with their own set of problems. Using a managed, garbage collected language is usually an even better idea (but I'm going to be flamed if I suggest this, so I won't). :) Of course, the best solution would be to use a language which cannot have dangling pointers / null references by design, like Ocaml - but suggesting that on gamedev would be akin to throwing petroleum into a raging fire...

Damn right - none of these languages you speak of are suitable for OS development; and won't your face be red when 0xDEADBEEF starts falling within valid memory range...

Oh, hang on - you tell me he's probably writing video games? Disregard. >_>

Share this post


Link to post
Share on other sites
Fiddler : Yeah , built - in garbage collectors are fun stuff indeed , but my target language is C++ unfortunately.

Ravyne : That's interesting to know , normal pointers are now appearing to be quite error prone , I guess it's time to convert to smart pointers.

Share this post


Link to post
Share on other sites
Between shared_ptr, weak_ptr, and auto_ptr, they have most of the bases covered, however you'll still need to deal with raw pointers often.

Learn what each of the smart pointers I mentioned does, and how to apply it -- then appply it when it fits -- otherwise you probably want a raw pointer.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this