Вектор общих указателей, проблемы с памятью после очистки вектора

Я понял, что после вызова vector.clear() которые содержат общие указатели, деструкторы объекта, которые владеют shared_ptr не выпускается.

пример кода можно увидеть ниже . Даже vector.clear() вызывается деструктор, вызываемый после того, как общий указатель выходит за пределы области.Мой вопрос: Должен ли я удалить все интеллектуальные указатели внутри вектора вручную, сбросив их? Есть ли более простой способ дать совет ?

Output :   

constructor
I am here
destructor

Code:

#include <vector>
#include <iostream>
#include <memory>

using namespace std;

class A
{
public:
    A(){cout << "constructor" << endl;};
    ~A(){cout << "destructor"  << endl;};
};

int main( )
{
    shared_ptr<A> sharedptr (new A);
    std::vector<shared_ptr<A> > test;
    test.push_back(sharedptr);

    test.clear();
    cout << "I am here" << endl;
}

3 ответов


у вас есть две копии shared_ptr<A> в этом случае одним из них является sharedptr переменная и другая как элемент в векторе.

сделать это вместо

test.push_back(std::move(sharedptr));

обратите внимание на оригинал sharedptr имеет внутреннее перемещение и больше не используется. Другое дело, не делайте ничего вообще, это совершенно правильное использование shared_ptr и sharedptr очистит себя после того, как он выйдет за рамки.


проблема возникает, когда push_back добавляет скопировать на shared_ptr вектору, оставляя исходное болтаться, пока main не существует. Если вы не делаете shared_ptr в основной области, проблема не возникает. Просто избегайте создания shared_ptr в основной области. Сделайте это как временное право в push_back звонок.

Output is now:   

constructor
I am almost there
destructor
I am here

New code:

#include <vector>
#include <iostream>
#include <memory>

using namespace std;

class A
{
public:
  A(){cout << "constructor" << endl;};
  ~A(){cout << "destructor"  << endl;};
};

int main( )
{
  vector<shared_ptr<A> > test;
  test.push_back(shared_ptr<A>(new A));
  cout << "I am almost there" << endl;
  test.clear();
  cout << "I am here" << endl;
  return 0;
}

здесь sharedptr и элемент вектор поделиться один и тот же объект, который приведет к вызову конструктора и деструктора только один раз.