C++ 共享指针的向量,清除向量后的内存问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19334889/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 22:44:10  来源:igfitidea点击:

Vector of shared pointers , memory problems after clearing the vector

c++memoryvectorsmart-pointers

提问by Kadir Erdem Demir

I realized that after calling vector.clear()which hold shared pointers, the destructors of the object which own by shared_ptris not being released.

我意识到在调用vector.clear()which 持有共享指针后,拥有的对象的析构函数shared_ptr没有被释放。

Code example can be seen below . Even vector.clear()being called, destructor called after shared pointer goes beyond the scope.My question is - do I have to delete all smart pointers inside the vector manually by resetting them? Is there any easier way that you can advice ?

代码示例如下所示。即使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;
}

回答by yngccc

you have two copies of shared_ptr<A>in this case, one is the sharedptrvariable and the other as an element in the vector.

shared_ptr<A>在这种情况下,您有两个副本,一个是sharedptr变量,另一个是向量中的元素。

do this instead

改为这样做

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

note now the original sharedptrhas it's internal moved and no longer usable. The other thing is don't do anything at all, this is a perfectly valid usage of of shared_ptr and sharedptrwill clean up itself after it goes out of scope.

请注意,现在原件sharedptr已在内部移动并且不再可用。另一件事是什么都不做,这是 shared_ptr 的一个完全有效的用法,并且sharedptr会在它超出范围后自行清理。

回答by Fred Hymanson

The problem arises when the push_backadds a copyof the shared_ptrto the vector, leaving the original dangling until main exists. If you don't make the shared_ptr in main scope, the problem does not happen. Just avoid making the shared_ptr in main scope. Make it as a temporary right in the push_backcall.

当问题出现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;
}

回答by daoluan

Here sharedptrand the element in vectorshare the same object which will result in invoking constructor and destructor only once.

这里sharedptrvector 中的元素共享同一个对象,这将导致只调用一次构造函数和析构函数。

回答by Drew Harwell

The reason the destructor isn't called until later is that your variable sharedptris still in scope until the end of your main(). There are a few ways around this if you really want it cleaned up before then. The most obvious way to fix this is to only use sharedptrin a quick block scope:

直到稍后才调用析构函数的原因是您的变量sharedptrmain(). 如果你真的想在那之前清理它,有几种方法可以解决这个问题。解决此问题的最明显方法是仅sharedptr在快速块范围内使用:

int main( )
{
    std::vector<shared_ptr<A> > test;
    {
      shared_ptr<A> sharedptr (new A);
      test.push_back(sharedptr);
    }
    test.clear();
    cout << "I am here" << endl;
}

Or alternatively, never create the sharedptrvariable at all:

或者,根本不要创建sharedptr变量:

int main( )
{
    std::vector<shared_ptr<A> > test;
    test.push_back( shared_ptr<A>(new A) );
    test.clear();
    cout << "I am here" << endl;
}