2015-11-19 5 views
4

я на Ubuntu 14.04 с помощью GCC 4.8.4 и у меня есть код, подобный следующему:Когда std :: shared_ptr выпускает свой объект?

std::shared_ptr<MyClass> my_shared_object = set elsewhere... 
MyFunction(*my_shared_object); 

Где MyFunction «s подпись выглядит следующим образом:

void MyFunction(const MyClass& my_object) 

Полный код может быть found here

Однако, я нахожу, что my_object фактически выходит за пределы области видимости в контексте MyFunction. Моя мысль заключалась в том, что my_shared_object будет выпускать свое содержимое только после того, как оно выходит из сферы действия, что означает, что после возврата MyFunction. Я не уверен, что я либо недопонимаю std::shared_ptr, либо, может быть, это ошибка GCC.

Я думаю, что вопрос сводится к: , когда я разыскиваю std :: shared_ptr, это гарантирует, что std::shared_ptr будет сохраняться до тех пор, пока используется разыменование?

+1

Выполнение разыменования 'std :: shared_ptr' приведет к открытому указателю, и нет возможности для' std :: shared_ptr' отслеживать, что происходит с дальнейшими копиями голого указателя. Если вы хотите, чтобы объект сохранялся во время действия вашей функции, вы должны передать значение 'std :: shared_ptr' по значению. Копирование 'std :: shared_ptr' сигнализирует предполагаемое поведение совместного владения. – Snps

+2

Общий указатель действителен до и после вызова функции (следовательно, ссылка тоже), если не будет глупого в другом месте .... –

+0

@Snps Я согласен с тем, что ваше решение устранит проблему. Тем не менее, я также чувствую, что @ ответ Дитера должен быть правильным, а '' my_shared_object'' не выходит из контекста, пока не вернется '' MyFunction''! Поэтому я думаю, возможно, компилятор каким-то образом переопределяет его. – kip622

ответ

5

Все, что находится под управлением std::shared_ptr, будет уничтожено в тот момент, когда нет std::shared_ptr, оставив заявку, все остальные способы ссылаться на нее не имеют значения.

И локальные переменные уничтожаются только при выходе из соответствующего объема. Выделение домена std::shared_ptr никоим образом не изменяет его.

+0

Как вы думаете, вероятно, что это некоторая оптимизация GCC, которая преждевременно освобождает shared_ptr, и вот почему разыменованный объект выходит из контекста в MyFunction? – kip622

+1

В вашем вопросе здесь нет ничего, что позволило бы изменить 'std :: shared_ptr' до того, как эта функция вернется, и я сомневаюсь, что gcc будет катастрофически неправильно оптимизировать ее. Проблема, вероятно, в другом месте. – Deduplicator

+1

@ kip622 Поскольку вы передаете ссылку 'const', как возможно, что объект выходит из сферы действия вашей функции? Вы даже не передаете ему объект, а атрибут 'const' квалифицированный. Где-то еще вы все начинаете. – 101010

4

std::shared_ptr не знает о вашей ссылке (или ваша ссылка не знает о std::shared_ptr) к объекту, который состоится, это известно только других std::shared_ptr с совместным владением одного и тем же объектом. Поэтому, как только последний std::shared_ptr выходит из сферы действия, объект разрушается, и вы оказываетесь в обмотанной ссылке.

Однако, это не должно быть здесь, и ваш std::shared_ptr должен быть правильно разрушен после того, как поток программы покинет область действия, которую я не понимаю, может произойти до вызова MyFunction.

+0

Тот же вопрос, что и для Deduplicator: Как вы думаете, вероятно, что это некоторая оптимизация GCC, которая преждевременно освобождает shared_ptr, и вот почему разыменованный объект выходит из контекста в MyFunction? – kip622

+0

Это действительно странно. Вы должны предоставить более сжатый MCVE. Ну, то, что вы связали, вовсе не MCVE. – LogicStuff

1

std :: shared_ptr сохраняет внутренний счетчик ссылок. Этот счет соответствует количеству объектов, разделяющих объект. Каждый раз, когда shared_ptr выходит из области видимости, внутренний счетчик ссылок уменьшается. , когда внутренний счетчик ссылок падает до нуля, память де-распределяется.

+0

Спасибо за объяснение. Думаю, я понимаю основы 'shared_ptr'. Проблема здесь в том, что она, кажется, освобождается до выхода из полного контекста, поскольку в вопросе описывается – kip622

+0

, вам нужно передать my_shared_object по значению или ссылке, чтобы счетчик ссылок увеличивался в пределах MyFunction. – Nandu

+0

Быть педантичным: это больше * собственность на объект *. И память может быть освобождена только в том случае, если последний 'std :: shared_ptr' откажется от своего требования, если нет' std :: weak_ptr' или объекта управления, и управляемый объект не был выделен сразу (например, std :: make_shared' будет делать). – Deduplicator

 Смежные вопросы

  • Нет связанных вопросов^_^