Подтвердить что ты не робот

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

Я понял, что после вызова 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;
}
4b9b3361

Ответ 1

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

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

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

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

Ответ 2

Проблема возникает, когда push_back добавляет копию shared_ptr к вектору, оставляя исходное зависание до тех пор, пока не будет существовать основная. Если вы не делаете 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;
}

Ответ 3

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