C ++ 11 хранит несколько общих указателей в виде необработанных указателей

Мой вопрос касается 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, но они не ответили на мой вопрос или, может быть, я не понял ответы …

16

Решение

Причина, по которой вы будете использовать shared_ptr Вы хотите, чтобы память, на которую она указывает, была освобождена, когда все указывающие на нее экземпляры выходят из области видимости. shared_ptr уничтожается сразу после звонка .get() на нем, так что у вас сразу есть свисающий указатель. Результат операции разыменования не определен, что означает, что он может возвращать или не возвращать значение, которое имеет смысл, или он может даже делать что-то совершенно не связанное (например, сбой).

Это особенность. Вы хочу это должно произойти: в противном случае у вас будет утечка памяти. Представьте себе этот код:

vector<int> integers;
integers.push_back(*make_shared<int>(6).get());

Если память не была освобождена, было бы ни за что выпустить его позже, потому что вы не сможете восстановить управляемый указатель shared_ptr.

11

Другие решения

Вы видите неопределенное поведение. Когда вы делаете это:

vector2.push_back(std::make_shared<int>(4).get());

Вы создаете временный shared_ptrи скопировать указатель на его управляемый объект в ваш vector, Это немедленно становится висящим указателем.

10

По вопросам рекламы [email protected]