Голый указатель на unique_ptr
-
21-12-2019 - |
Вопрос
У меня есть структура с вектором, и мне нужно сохранить указатель на один из ее элементов.С голыми указателями я бы сделал следующее:
#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;
}
Теперь я могу избавиться от голого указателя с помощью 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;
};
Поскольку C++11 еще не реализует make_unique, как я могу сделать то же самое с unique_ptr?Я попытался назначить передний элемент, сделав uv
а unique_ptr
и звоню uv.reset(&v.front());
, но я получаю следующую ошибку:
malloc: *** error for object 0x7f856bc0bcf0: pointer being freed was not allocated
Любая помощь?Спасибо
Решение
Философия, лежащая в основе std::unique_ptr
это из владение, т.е.это объект, владеющий областью памяти, связывающий время жизни последней со своим собственным.
Ан std::vector
идет по тому же пути:он претендует на владение элементами, которые он содержит.Таким образом, когда его деструктор запускается, он запускает деструкторы своих элементов (если они относятся к пользовательским типам).
В твоем случае, v
владеет v.front()
, но вы также возложили эту ответственность на uv
.Сейчас, оба из них попытается уничтожить тот же объект.
Здесь лучше использовать необработанный указатель или (лучше) итератор, поскольку он используется только как наблюдатель.