About Pointers

Hi everyone

i have a few questions about pointers and even though i have made research my humble mind failed to understand.

1. what are the benefits of using unique and shared pointers. and when exatly they are useful

2. if i have an object which is pointed by two pointer "a" and "b" which one would be fine, to free them both or only one is enough.(although this is a problem that i do not fully understand what freeding)

thx in advance to you all
1. You no longer have to worry about manually managing your pointers and remembering to call delete or delete[] exactly once, as well as the fact that you no longer have to document when to free the associated memory (if at all) and if the pointer is shared by other parts of the code, since the names f the wrapper classes do that already.

2. Pointers hold the address of a dynamically allocated object. When you write delete p; or delete[] p;, you are not changing the pointer in any way - instead, you are destructing the object at the address the pointer points to, and then marking that memory as free. If you have two pointers pointing to the same object, you should only call delete or delete[] on one of them. This is why the shared_ptr class exists.

Remember: if you have to write delete or delete[] in your code, you are not writing proper code.
Last edited on
When you new/delete (or malloc/free --- but you shouldn't be using those in C++)... you are not doing anything special with the pointer. You are manipulating a separate, unnamed object.

Example:

1
2
3
4
5
6
7
8
int* ptr;  // 'ptr' is our pointer
ptr = new int;  // this creates a new, unnamed int.  Let's call this int 'foo'
  // we then assign a pointer to foo to our pointer, 'ptr'

*ptr = 5;  // this assigns 5 to 'foo'

delete ptr; // this deletes 'foo' (since 'ptr' points to 'foo').  IT DOES NOT
    // delete 'ptr' 



So to answer your 2nd question:

1
2
3
4
5
6
7
8
int* a = new int; // create 'foo'.  make 'a' point to it
int* b = a;  // make 'b' point to the same thing 'a' points to

// here, both a and b point to foo.

delete a;  // this deletes foo
delete b; // <- this attempts to delete foo AGAIN which is BAD.  foo has already
  //  been deleted.  This will likely cause your program to crash. 


So the answer to the 2nd question is: You have exactly 1 'delete' for every 'new'. The number of pointers does not matter. in this case, you would delete only one of the pointers because you only allocated one of them.




As for the 1st question...

shared_ptr and unique_ptr automate the cleanup process:

1
2
3
4
std::unique_ptr<int> ptr( new int ); // create 'foo', make 'ptr' point to it

// no need to delete it... ever.  unique_ptr will delete it
//   in the destructor.  So cleanup will happen automatically 


unique_ptr assumes "ownership" of 'foo'. So as soon as the unique_ptr goes out of scope (dtor called), 'foo' will be deleted.

shared_ptr is the same idea... only instead of having 1 owner, you can have multiple pointer sharing ownership... meaning that 'foo' would only be deleted when all shared_ptrs go out of scope (vs. unique_ptr where there is only 1 pointer)

shared_ptr has pitfalls associated with it, where it's possible to have circular dependencies... leading to leaks because neither pointer ever goes out of scope. So you generally should stick to unique_ptr unless you have a good reason not to.


EDIT: ninja'd by LB
Last edited on
I agree with Disch about avoiding shared_ptr unless you're very confident in what you're doing. Generally, everything will be wrapped in unique_ptr and you just pass references to the wrapped object to code that needs access. Just be sure the lifetime of the unique_ptrs outlasts the lifetime of the references, or document lifetime rules in your code.

The only reason I can think of to use shared_ptr is when you need to ensure the object is always valid when accessible but are not sure of the lifetime necessary - the places where this would actually happen are rare and can even be considered as demonstrating flaws in your design. Generally, using std::move on unique_ptr is sufficient.
thx to all of you.

now i understand quite better
Topic archived. No new replies allowed.