есть несколько недоразумений, но я попытаюсь объяснить: в c++ объекты хранятся либо в стеке, либо в куче. объекты, созданные в стеке, будут уничтожены, а их память будет освобождена, как только вы покинете область, в которой они объявлены. это происходит полностью автоматически для вас. Например:
int bla()
{
int a = 1;
int b = 2;
int result = a+b;
return result;
}
в этом примере 3 int
объекта будут созданы, когда программа войдет в функцию bla
, и будут уничтожены, когда функция вернется соответствующим образом.
тогда у вас есть куча. вы можете создавать объекты в куче через new
. эти объекты переживают область, в которой они были созданы, но вы должны помнить об уничтожении объектов через delete
. поскольку это распространенная ошибка и источник утечек памяти, стандартная библиотека предоставляет вспомогательные классы (например, shared_ptr
, которые вы уже нашли) для решения этой проблемы. идея в том, что shared_ptr
object возьмет на себя ответственность за удаление данного объекта (который должен быть в куче (!) (да, вы можете обойти это с помощью специального удаления, но это немного более продвинуто, чем это объяснение)) как только сам shared_ptr будет уничтожен. как следует из названия, целью shared_ptr
является совместное использование. чтобы поделиться, просто скопируйте файл shared_ptr. реализация shared_ptr
имеет собственный конструктор копирования и оператор присваивания копии, который будет обрабатывать это, увеличивая счетчик использования и копируя адрес объекта, который обрабатывается в данный момент. и это единственный способ, которым объект shared_ptr узнает, есть ли другие экземпляры, управляющие тем же объектом, или нет. поэтому, чтобы увеличить количество использований, вам нужно сделать копию файла shared_ptr
.
теперь позвольте мне объяснить, что пошло не так:
ваш первоначальный Node node = Node(10);
создается в стеке (как и целые числа выше). поэтому нет необходимости вручную управлять временем жизни. вы создали shared_ptr
, управляющий адресом этого узла. это ошибка. как только вы покинете область действия, shared_ptr
И сам объект узла (благодаря автоматизму в стеке) удалит объект узла. и это плохо.
давайте представим, что ошибки 1 не существует. поэтому у нас есть вторая ошибка: вы создаете второй, отдельный shared_ptr
вместо того, чтобы копировать из первого. теперь оба существующих shared_ptr
не знают друг о друге и каждый из них попытается удалить объект узла. так что у нас снова двойное удаление.
давайте представим, что вы хотите, чтобы ваш объект Node действительно управлялся shared_ptr
, вам нужно начать с одного shared_ptr, а затем скопировать из него столько, сколько вы хотите поделиться им. для создания первого у вас есть 2 возможности:
std::shared_ptr<int> mysharedpointer (new int(ANYNUMBER));
auto mysharedpointer = std::make_shared<int>(ANYNUMBER);
обычно вы предпочитаете второй вариант, так как он дает небольшое преимущество в производительности и большую безопасность при использовании в контексте вызова функции.
если теперь вам нужен второй shared_ptr
, разделяющий владение с первым, вы можете сделать это, скопировав первый указатель:
auto mysecondsharedpointer = mysharedpointer;
и вуаля у вас есть копия, связанная с общим владением.
(все это немного упрощено, и я уверен, что что-то упустил. Не стесняйтесь завершать ответ)
person
phön
schedule
12.01.2018
(shared_ptr<Node>)&node
неверно на нескольких уровнях. - person user7860670   schedule 12.01.2018ptr2 = ptr1;
, и вы НЕ ДОЛЖНЫ брать адрес локальной переменной, так как она попытается удалить в конце программы и произойдет ужасный сбой. - person Ken Y-N   schedule 12.01.2018ptr1
иptr2
, они являются временными и будут уничтожены или получатmoved
. - person sameerkn   schedule 12.01.2018