Почему разделяемый указатель не удаляет память? - PullRequest
1 голос
/ 03 октября 2019
shared_ptr<string> pNico(new string("Nico"));
shared_ptr<string> pJutta(new string("Jutta"));
// put them multiple times in a container
vector<shared_ptr<string>> whoMadeCoffee;
whoMadeCoffee.push_back(pJutta);
whoMadeCoffee.push_back(pJutta);
whoMadeCoffee.push_back(pNico);
whoMadeCoffee.push_back(pJutta);
whoMadeCoffee.push_back(pNico);

pNico = nullptr;         
whoMadeCoffee.resize(2);

В конце программы, когда уничтожается последний владелец строки, общий указатель вызывает delete для объекта, на который он ссылается. Такое удаление не обязательно должно происходить в конце области. Например, присвоение nullptr pNico или изменение размера вектора таким образом, чтобы он содержал только первые два элемента s, приведет к удалению последнего владельца строки, инициализированной nico.

(из Josuttis. , Николай М .. "Стандартная библиотека C ++.")

Мой вопрос заключается в том, почему в вышеупомянутом случае не гарантируется, что память объекта "Nico" будет удалена в конце области действия?

Хотя, если мы сделаем это вместо этого

whoMadeCoffee.resize(2);
pNico = nullptr;

Память, связанная с "Nico", действительно будет удалена.

Может кто-нибудь объяснить, пожалуйста, разницу?

1 Ответ

4 голосов
/ 03 октября 2019

В конце программы, когда последний владелец строки уничтожается, общий указатель вызывает delete для объекта, на который он ссылается. Такое удаление не обязательно обязательно должно произойти в конце области.

string("Nico") будет уничтожено, когда счетчик ссылок достигнет 0. В вашем примере он достигает0 (для Nico) даже до достижения конца области.

Он может жить вне его области, если вы поделитесь с кем-то другим из вашей текущей области, например, с функцией, которая возвращает shared_ptr или здесьеще более простой пример:

shared_ptr<string> pNico0(new string(""));
{ 
    shared_ptr<string> pNico1(new string("Nico"));
    pNico0 = pNico1; // pNico0 reference count = 2
}
// pNico0 reference count = 1

Live on godbolt

...