Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pointer to stack object without ownership

I want to have a class with a pointer member variable. This pointer should point to an object which may be stack-allocated or heap-allocated. However, this pointer should not have any ownership. In other words, no delete should be called at all when the pointer goes out of scope. I think that a raw pointer could solve the problem... However, I am not sure if there is a better C++11 approach than raw pointers?

Example:

class foo{
public:
    bar* pntr
};

int main(){
    bar a;
    foo b;
    b.pntr=&a;
}
like image 495
Humam Helfawi Avatar asked Jan 02 '16 16:01

Humam Helfawi


People also ask

What is std:: unique_ ptr in C++?

(since C++11) std::unique_ptr is a smart pointer that owns and manages another object through a pointer and disposes of that object when the unique_ptr goes out of scope. The object is disposed of, using the associated deleter when either of the following happens: the managing unique_ptr object is destroyed.

Can pointers be on stack?

The stack pointer -- also referred to as the extended stack pointer (ESP) -- ensures that the program always adds data to the right location in the stack. The stack stores data from the top down, following a last in, first out (LIFO) data structure.

How to transfer ownership unique_ ptr?

In C++11 we can transfer the ownership of an object to another unique_ptr using std::move() . After the ownership transfer, the smart pointer that ceded the ownership becomes null and get() returns nullptr.

Should pointers be avoided?

It is best to avoid using pointers in C++ as much as possible. The use of pointers can lead to confusion of ownership which can directly or indirectly lead to memory leaks.


2 Answers

Raw pointers are perfectly fine here. C++11 doesn't have any other "dumb" smart pointer that deals with non-owning objects, so you cannot use C++11 smart pointers. There is a proposal for a "stupid" smart pointer for non-owned objects:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4282.pdf

already implemented experimentally as std::experimental::observer_ptr (thanks @T.C. for the hint).

Another alternative is to use a smart pointer with a custom deleter that doesn't do anything:

#include <memory>

int main()
{
    int a{42};

    auto no_op = [](int*){};
    std::unique_ptr<int, decltype(no_op)> up(&a, no_op);
}

or, as mentioned by @T.C. in the comment, a std::reference_wrapper.

As mentioned by @Lightness Races in Orbit, a std::weak_ptr may also be a solution, as the latter is also a non-owning smart pointer. However a std::weak_ptr can only be constructed from a std::shared_ptr or another std::weak_ptr. A serious downside is that the std::shared_ptr is a "heavy" object (because of the internal reference counting mechanism). Note that even in this case the std::shared_ptr must have a trivial custom deleter, otherwise it corrupts the stack for pointers to automatic variables.

like image 139
vsoftco Avatar answered Oct 15 '22 21:10

vsoftco


Using a raw pointer is perfectly ok here as you don't intend to let the pointer have ownership of the resource pointed to.

like image 36
Felix Glas Avatar answered Oct 15 '22 21:10

Felix Glas