Getting address of object pointed by reference - c++

I'd like to enforce that an object should exist before passing it to a function:
void Class::setStoredObject(MustExist& obj) {
stored_object = &obj;
}
// Lifetime of ptr is my responsibility
std::unique_ptr<MustExist> ptr = std::make_unique<MustExist>();
classObject.setStoredObject(*ptr);
anyway I also need to store that object (big one) by reference or address so I usually grab a pointer to it.
Is this safe to do? I.e. getting the address of a reference to refer to the original pointed-to object.
Alternatively, any other/better way that I could achieve this?

There's nothing wrong with this, per se. Of course, if the original object goes out of scope and gets destroyed, the saved pointer to the object will no longer be valid.

The safest way to ensure that you get an existing object and that it won't be deleted without a possibility to check this, is by instantiating and passing a shared_ptr. This way you can choose to store the shared_ptr so you're sure it won't disappear (but then you need some clean up code) or store as weak_ptr so you can only use it when it still exists.
Storing raw pointers of objects controlled by smart pointers can lead to very subtle issues, that are difficult to trace back to code.

In general, it is not a good design to get and to use a raw pointer out of std::unique_ptr as it breaks all the idea of it.

Dereferencing ptr and passing the object by reference is not a good semantic for what you are trying to do.
If the caller context needs the unique_ptr you should use:
void Class::setStoredObject(std::unique_ptr<MustExist> obj_ptr)
and do the call
classObject.setStoredObject(std::move(ptr));
expressing the fact that the calling context is giving away ownership.
Otherwise you can give up the unique_ptr altogether (its existence is not justified in your example). In this case I would consider either of:
void Class::setStoredObject(const MustExist& obj) // ok for copy
void Class::setStoredObject(MustExist&& obj) // move semantics, expressing the fact that the caller is done using the object.

Related

C++ pointers and memory leak

I'd like to illustrate one thing I've seen:
class Something {};
void do_something(const Something *p_sth) {}
Then:
do_something(new Something());
should cause a memory leak because when you call new you should also always call delete, right? Would this be a good solution?
void do_something(const Something *p_sth)
{
delete p_sth;
}
Or is it better to use references &? I also find out that smart pointers can solve this, so delete isn't required (it seems as a good thing but I have never used it before). I just want to know what's the best solution for this to avoid the memory leak. Thanks
*Thank you all for your answers. It helped me to clear up few things. I'm also sorry for the code I posted as it was maybe too general.
Your suggestion of assuming the ownership of the pointer and deleting the object has problems.
That behaviour is not idiomatic in c++. Programmers expect that they must delete every object that they allocate with new. If a user of your function expects that they're responsible for deleting the object whose address they pass to the function, then your solution breaks apart. Also, it prevents using your function with objects that must keep existing after the call has ended:
Something* s = new s();
do_something(s);
s.foo() // oops, object was deleted, I can't use it anymore
delete s; // oops, double delete because I'm for some reason not responsible for deleting the object that I allocated
Your solution also prevents using automatically and statically allocated objects with the function.
Something s;
do_something(&s); //oops, do_something assumes that object is dynamically allocated
All of these caveats would have to be documented to the user of the function.
A raw pointer without deleting inside the function has none of these problems. Managing the callers memory should really not be the responsibility of your function. Doing that would break the single responsibility principle. There's nothing wrong with raw pointer parameters when you don't want to transfer or share ownership. If you do want to imply changes in ownership, then use smart pointers which were designed exactly for that.
Smart pointers don't have some of the above problems, but they still prevent using the function with automatic and static objects.
A reference parameter is in many cases ideal. It communicates the caller that they're still responsible for the object. As a bonus, The lack of need for addressof operator allows slightly nicer syntax. Sure, the caller may still forget to manage their memory, but as I pointed out, that shouldn't be your responsibility.
References have one potential drawback. They can't be null. If you don't need null, then it's actually an advantage.
Which solution is ideal, depends on what you need. Following is not true for all corner cases, but should hold for most common cases:
If you want to modify the object, then pass a reference.
Unless you need null, in which case use a pointer
If you just want to read the object, then
If the object is copyable, small (size less than or equal to word), doesn't cointain pointers to dynamic objects and not polymorphic, then pass by value
Otherwise or if you don't know those things because you're writing a template, pass a const reference
Unless you need null, in which case use a pointer
If you want to If you want to transfer ownership, then use unique_ptr
If you want that ownership to be shared, then use shared_ptr
Best is to use a smart pointer
class Something {};
void do_something(std::shared_ptr<Something> p_sth)
{
...
}
That way the ownership is clear when you look at the prototype as well as you get an automatic delete when you leave scope.
I just want to know what's the best solution for this to avoid the memory leak. Thanks
The best solution to ensure there are no memory leaks would be to use std::shared_ptrwhich is a smart pointer which, as soon as it does not have any references, deletes itself. This pointer is best if you have more than on reference to the same pointer. Use std::unique_ptr if there is only one reference at a given time.
This will prevent memory leaks and I also prefer using smart pointers rather than standard pointers as they are very powerful. Also, retaining to the question:
Or is it better to use references &?
Use references wherever you need to reference the object, if you delete the reference, being a smart pointer, it will delete the pointer as well (Being there are no other references to that pointer)
I hope this answers your questions :)
Prefer to avoid the use of raw pointers.
If you do not need a heap allocation and can use a stack allocated variable, then prefer to pass by reference (or even pass by value if an appropriate move constructor is in place, but that's a topic for another day).
If you need a heap allocation (for polymorphism, dependency injection, information hiding, transfer of ownership etc.) then determine what the ownership semantics will be for that object and use the appropriate smart pointer to manage those semantics.
If all else fails and you must use a raw pointer (perhaps you are dealing with a legacy interface or a C interface, or something similar) then again, clearly define your ownership semantics and document them to make it clear who is responsible for deleting the heap allocated object, etc.
If you must have a raw pointer to a stack allocated object then document that you will not be deleting the pointer and be careful about documenting the lifetime of the pointer to avoid accessing the object after it has gone out of scope.
Cleanest solution would be to avoid the pointer completely.
And yes, a reference is a good idea.
void do_something(const Something &p_sth) {}
Then you can declare your 'something' on the Stack.
void function_that_does_something()
{
Something mySomething;
do_something( mySomething );
}
It is always best to let the compiler do the cleanup for you.

Equivalent implementation of unique_ptr::reset for raw pointers?

I'm trying to refactor a section of code into a separate object/file. To maintain the same behavior, my code needs to use pointers to key components in the original file, which are declared as unique_ptrs.
I was thinking to extract the raw pointers and pass them to my object since my portion isn't responsible for deleting any pointers. (I hope I'm understanding ownership semantics correctly, still relatively new to C++). The only caveat is that I need to replicate unique_ptr::reset's behavior. Will this code do the same thing reset does?
template <typename Type>
void reset(Type* &current_ptr){
Type* old_ptr = current_ptr;
current_ptr = new Type();
if(old_ptr != null)
delete old_ptr;
}
If you need to call reset then you are in fact actually deleting pointers, and doing so outside the context of the unique_ptr's destructor is a recipe asking for disaster (even if your code appears to work it may still be undefined behavior).
If in fact all you need is to dereference (primarily * and ->) the unique_ptr then you should pass and use a reference to the object in your new code, making sure that the unique_ptr can't die while you're using the reference.
If you need to reassign or reset the smart pointer you'll need an alternate approach, but you didn't supply enough information in the question to help scope out such an alternate approach.
No, that's not what reset() does.
As pointed out in the comments, the features of smart pointers are about ownership, not pointers themselves. Ownership means responsibility, so if a unique_ptr owns an object, it is its "job" to delete it when the unique_ptr dies itself. shared_ptr are a little more complex, but they are also all about deleting the object "when the time comes", and taking that responsibility off of you, the programmer.
unique_ptrs are unique, that is, no two unique_ptrs should ever own the same object.
Now, the reset() method is a way of saying "hey, unique_ptr, I've got a new pointer for you to manage, so destroy the old one (if you had any) and take ownership of this new one that I'm giving you. From now on, this is the one you'll destroy when you die yourself."
This operation has no meaning with raw pointers, since they do not hold any ownership and won't kill themselves off at the right time or anything like that.
So, comparing that with your code, the similarity is that the old pointer is indeed deleted. But apart from the essence being missing (that is, the raw pointer won't remember to delete itself and does not hold ownership), the normal reset() is given a pointer, it does not create a new object by itself.

How to enforce non-ownership of a pointer?

I have a method which creates an object in an auto_ptr, sticks that auto_ptr into a vector, and then returns a raw pointer to the object for convenience.
The problem with this design is that it returns a raw pointer. It's really easy for the caller to misunderstand that this pointer is non-owned and wrap the result of this call into a managed pointer, which causes a memory access violation when that memory gets double free'd.
int main (void)
{
{
std::auto_ptr<int> foo = ThisMethodReturnsNonOwningPtr(); // Uhoh
}
ThisMethodUsesThePtr(); // Crash
return 0;
}
Ideally, I would like to return something like a pointer which can not be converted to a managed pointer so I don't have to worry about the caller doing this.
Alternatively, I might just return an index into the array, but it's real convenient just being able to pass the pointer around, and who knows maybe I will end up shuffling or sorting the array later.
First, if you can stick an auto_ptr into a vector, it's time to
upgrade your compiler or your library. This hasn't been legal
since the first standard in 1998. If you've got C++11, you can
use std::unique_ptr; if not, you'll need to keep raw pointers
in the vector. In both cases, you'll want to wrap the vector:
with std::unique_ptr, so that the client doesn't have to do
anything fancy to get the actual pointer, and with raw pointers,
so that you can manage the memory associated with them.
For the rest, just return a raw pointer. If you have
programmers that go around deleting random pointers, you're sunk
anyway; most of the time, raw pointers are for navigation, and
are just as likely to point to an object with static lifetime as
to anything else.
Stop using auto_ptr and start using unique_ptr or shared_ptr. The latter has reference counting so you can safely return the object and others can use it. The data it points to will not be freed until all references are released.
there is no other alternative if you need to safely return a pointer to the object and still be able to alter the vector. You could use a unique_ptr to prevent a caller from treating the returned pointer as if it owned it.
Last resort is to slap comments on the code to say that the vector owns the object and the pointer is only to be used as a convenience. Its not as good as getting the compiler to check calling code, but it can be the only way if you restrict your options as you mentioned.
Create a wrapper class template raw_ptr<T> which encapsulates a T*.
If you now implement operator* and operator-> but no conversion operator, you can no longer assign this pointer to another smart pointer, because that assignment would require two custom conversions (raw_ptr<T> → T* → smart_ptr<T>), which is not allowed in C++.
Notice that, as others have said, you should not use auto_ptr<T> – it’s deprecated for good reasons. Use std::unique_ptr<T> instead. For one thing, you cannot actually safely stick auto_ptrs into a std::vector, great care has to be taken to not accidentally copy (and thus invalidate) such pointers.
I'm always reluctant to write answers that depend on boost since not everyone is able to use it and it's almost always overkill to pull it in for just one little thing, but if you have it anyway, you could return a boost::optional<&>. On the surface it doesn't seem an optional reference could work, but it (mostly) does. See boost's documentation.
This would give you the nullability you require (return boost::none to indicate an error) while making it very clear that the caller is not to take ownership of the object.
If you don't want the object to be deleted in conventional means using delete operator, you could make the destructor of the class private and implement destroy() function which self-destructs the object.
Better would be if you could make the function return something like shared_ptr.
A third option could be just to have a class something like template<typename> struct non_ownership_ptr; which the function returns instead of a raw pointer. This pointer class just holds the pointer and you would have to explicitly use auto_ptr<T> p=foo().non_owned_ptr; to avoid (or at least reduce) accidental assignment to auto_ptr or such.

How do I prevent deletion of a pointer without using const?

I have a class that contains a vector of object pointers. I have a GetObject(..) function in that class that looks through the vector, finds the object desired, and returns a pointer to it. However, if the user of the class does a delete() on that returned pointer, my program will crash because the vector still has a pointer to that, now invalid, object. So, in my GetObject() class, I can return a const pointer, but that doesn't solve the problem because you can still delete the object. The object is mutable so I can't return a pointer to a const object. I suppose I could prevent deletion by returning a reference to the object but I have my function returning NULL if there is an error. I guess I can pass back the object reference via the parameters and then return and error number like this
//-1 on object on found. 0 for success. Object is passed back in
// the function parameter result.
int MyObject::GetObject(int object_id, Item& result)
Is this the best solution for such a situation?
The best way to solve this problem is to use a shared-ownership smart pointer like shared_ptr, which you can find in Boost, C++ TR1, and C++0x.
A smart pointer is a container that manages the lifetime of your dynamically allocated object for you. It takes responsibility for deleteing the object when you are done using it.
With a shared ownership smart pointer, you can have multiple smart pointers that all share ownership of the dynamically allocated object. A reference count is kept that keeps track of how many smart pointers have ownership of the object, and when the last owning smart pointer is destroyed, the dynamically allocated object is deleted.
It is extremely difficult to manage resources manually in C++, and it's very easy to write code that looks correct and works right most of the time but that is still not correct. By using smart pointers and other resource-owning containers (like the standard library containers), you no longer have to manage resource manually. It is significantly easier to write correct code when all of your resource management is automatic.
Automatic resource management in C++ is accomplished using a design pattern called Resource Acquisition is Initialization (RAII), which is arguably the most important design pattern you as a C++ programmer should become familiar with.
Anybody in your code could also try to de-reference NULL. You going to stop them doing that too? If your container owns the object, and you make this clear (returning a raw pointer is usually pretty clear or mention in docs), then anyone who deletes it, the result is their own fault. The only way that you could guarantee the prevention of the deletion of the object is to prevent the user from ever gaining a native reference or pointer - in which case they just can't access the object.
Who are clients of your class? If they are not your mortal enemies you could just ask them nicely not to delete the object. Otherwise, there will always be a way for "them" to mess you up.
Okay, one possible solution is to make destructor private. That will prevent everyone from deleting the object. But then the object has to delete itself (delete this) somehow, maybe through some function called DeletObjectButDontBlameMeIfAppCrashes. If the owner is some other class then you can set the destructor to protected and owner class as friend of this class.
You should return a reference to the object. There are two ways to handle the case when there is no object found.
First, you can use the Null Object Pattern in order to implement a special value for that case. That might not make sense for your case though.
The other way is to split it up into two methods, one which can be used to check if an appropriate element exists, and one to retrieve it.
Many STL-containers or algorithms implement both of these, either by returned a past-the-end iterator, or by having empty() returns false as a prerequisite of calling a method like front or back.
If you can use the boost libraries, smart pointers can be used to ensure that pointers stay valid. Essentially, each reference to a smart pointer increases its "use count" by 1. When the reset function is called on a reference, the reference goes away and the use counter decrements. As long as some object is still holding on to a smart pointer, the reference will be valid. Note that the other classes will be able to change what its pointing to, but can't delete it.
(My description deals mainly with smart pointers specifically - the different types of pointers vary a little, but the general idea remains the same).

How to intentionally delete a boost::shared_ptr?

I have many boost::shared_ptr<MyClass> objects, and at some point I intentionally want to delete some of them to free some memory. (I know at that point that I will never need the pointed-to MyClass objects anymore.) How can I do that?
I guess you can't just call delete() with the raw pointer that I get with get().
I've seen a function get_deleter(shared_ptr<T> const & p) in boost::shared_ptr, but I'm not sure how to use it, and also it says experimental right next to it. (I think I have Boost 1.38.)
Maybe just assign a new empty boost::shared_ptr to the variable? That should throw away the old value and delete it.
You just do
ptr.reset();
See the shared_ptr manual. It is equivalent to
shared_ptr<T>().swap(ptr)
You call reset on every smart pointer that should not reference the object anymore. The last such reset (or any other action that causes the reference count drop to zero, actually) will cause the object to be free'ed using the deleter automatically.
Maybe you are interested in the Smart Pointer Programming Techniques. It has an entry about delayed deallocation.
If you want to be able to intentionally delete objects (I do all the time) then you have to use single ownership. You have been lured into using shared_ptr when it is not appropriate to your design.
The whole point of boost::shared_ptr<T> is that the pointee object will be deleted exactly at the moment when no shared_ptr<T>s point at it -- that is, when the last shared_ptr<T> pointing at this object goes out of scope or is reassigned to point to a different object. So, all you have to do to delete an object is make sure there are no shared_ptr<T>s pointing at it. E.g. if you only have a single shared_ptr<T> called p pointing at an object, either let it fall out of scope, or call p.reset() (equivalent to p = NULL for a plain pointer), or assign it to point at something else.
If you have two shared_ptr<T>s pointing at the object, you'll need to reassign both of them.
EDIT: Thanks to dehmann for pointing out that p = NULL; is not actually valid code for a shared_ptr<T>... :)
What you want to do is return weak references using boost::weak_ptr that can be converted to a shared_ptr when needed. This can allow you to control the lifetime of the object in the shared_ptr and those that want to access it can hold onto the weak_ptr and try to convert to a shared_ptr. If that convert fails, then they can re-query and bring the object back into memory.