С++ 11 сохранение нескольких общих указателей в качестве исходных указателей
Мой вопрос касается shared_ptr
и make_shared
в С++ 11. У меня два вектора, первый хранит интеллектуальные указатели, а второй хранит исходные указатели. Первый вектор работает так, как я это сделал, но vector2 просто запутывает...
Пример кода
#include <iostream>
#include <vector>
#include <memory>
int main() {
std::vector<std::shared_ptr<int>> vector1;
vector1.push_back(std::make_shared<int>(1));
vector1.push_back(std::make_shared<int>(2));
vector1.push_back(std::make_shared<int>(3));
std::vector<int*> vector2;
vector2.push_back(std::make_shared<int>(4).get());
vector2.push_back(std::make_shared<int>(5).get());
vector2.push_back(std::make_shared<int>(6).get());
std::cout << "vector1 values:" << std::endl;
for(auto &value: vector1) { std::cout << *value << std::endl; }
std::cout << "vector2 values:" << std::endl;
for(auto &value: vector2) { std::cout << *value << std::endl; }
return 0;
}
Выход
vector1 values:
1
2
3
vector2 values:
6
6
6
Вопрос
Я понимаю, что было бы намного проще создавать исходные указатели для начала и не пытаться преобразовывать интеллектуальные указатели, но мне было любопытно узнать почему это происходит? Также почему каждое нажатие меняет все значения в vector2?
Ссылки
Вот несколько вопросов, которые я нашел в stackoverflow, но они не ответили на мой вопрос или, может быть, я не понял ответы...
Ответы
Ответ 1
Причина, по которой вы будете использовать shared_ptr
, - это то, что вы хотите, чтобы память, на которую указывает, была освобождена, когда все экземпляры, указывающие на нее, выходят за рамки. shared_ptr
уничтожается сразу после вызова .get()
на нем, поэтому у вас сразу есть висячий указатель. Результатом операции разыменования является undefined, что означает, что оно может или не может вернуть значение, которое имеет смысл, или может даже сделать что-то совершенно не связанное (например, сбой).
Это функция. Вы хотите, чтобы это произошло: в противном случае вы будете пропускать память. Представьте себе этот код:
vector<int> integers;
integers.push_back(*make_shared<int>(6).get());
Если память не была освобождена, после этого не было бы возможности ее освободить, потому что вы не смогли восстановить управляемый указатель shared_ptr.
Ответ 2
Вы видите поведение undefined. Когда вы это сделаете:
vector2.push_back(std::make_shared<int>(4).get());
Создается временный shared_ptr
и копируется указатель на его управляемый объект в vector
. Это немедленно становится висящим указателем.