Мой вопрос касается shared_ptr
а также make_shared
в C ++ 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, но они не ответили на мой вопрос или, может быть, я не понял ответы …
Причина, по которой вы будете использовать shared_ptr
Вы хотите, чтобы память, на которую она указывает, была освобождена, когда все указывающие на нее экземпляры выходят из области видимости. shared_ptr
уничтожается сразу после звонка .get()
на нем, так что у вас сразу есть свисающий указатель. Результат операции разыменования не определен, что означает, что он может возвращать или не возвращать значение, которое имеет смысл, или он может даже делать что-то совершенно не связанное (например, сбой).
Это особенность. Вы хочу это должно произойти: в противном случае у вас будет утечка памяти. Представьте себе этот код:
vector<int> integers;
integers.push_back(*make_shared<int>(6).get());
Если память не была освобождена, было бы ни за что выпустить его позже, потому что вы не сможете восстановить управляемый указатель shared_ptr.
Вы видите неопределенное поведение. Когда вы делаете это:
vector2.push_back(std::make_shared<int>(4).get());
Вы создаете временный shared_ptr
и скопировать указатель на его управляемый объект в ваш vector
, Это немедленно становится висящим указателем.