Naked pointer to unique_ptr
-
21-12-2019 - |
Question
I have a structure with a vector and I need to store a pointer to one of its items. With naked pointers, I'd do like this:
#include <iostream>
#include <vector>
#include <memory>
#include <unistd.h>
struct A {
A () {
v = {1, 2, 3, 4};
uv = &v.front();
}
std::vector<int> v;
int* uv;
};
int main()
{
A a;
std::cout << *a.uv << std::endl;
return 0;
}
Now, I can get rid of the naked pointer with make_shared
:
struct A {
A () {
v = {1, 2, 3, 4};
uv = std::make_shared<int>(v.front());
}
std::vector<int> v;
std::shared_ptr<int> uv;
};
Since C++11 doesn't implement make_unique yet, how can I do the same thing with a unique_ptr? I tried assigning the front element by making uv
a unique_ptr
and calling uv.reset(&v.front());
, but I get the following error:
malloc: *** error for object 0x7f856bc0bcf0: pointer being freed was not allocated
Any help? Thanks
Solution
The philosophy behind std::unique_ptr
is that of ownership, i.e. it's an object that owns a region of memory, tying the lifetime of the latter to its own.
An std::vector
follows the same path: it claims ownership of the elements it contains. Thus, when its destructor runs, it triggers the destructors of its elements (if they are user-defined types).
In your case, v
owns v.front()
, but you also gave this responsibility to uv
. Now, both of them will try to destroy the same object.
It is better to use a raw pointer here, or (better) an iterator, since it's used as an observer only.