我的共享指针导致内存泄漏?

时间:2019-04-30 23:44:15

标签: c++ memory memory-management memory-leaks

在我的基类中,我有一个派生类的指针向量,例如

std::vector<std::shared_ptr<Fing*>> files;

在派生的抽象类中,我有一个工厂方法,看起来像

static std::shared_ptr<Fing*> create(const std::string filetype, const std::string &path);

派生的抽象类Fing *还有其他三个派生自其的类,我将其称为派生A,B,C。所以我在shared_ptr基类中的向量实际上更像是shared_ptr<A* or B* or C*>

的向量

所以工厂方法本身看起来像

shared_ptr<Fing*> Fing::create(const std::string fileType, const 
string &filepath){

if (fileType == "a"s){
    return make_shared<Fing*>(new A(filepath));
}
if (fileType == "b"s){
    return make_shared<Fing*>(new B(filepath));
}
    return make_shared<Fing*>(new C(filepath)); }

我这样称呼工厂方法

shared_ptr<Fing*> newA(Fing::create("a","path here"));

像这样把它推到我的载体上

myfiles.emplace_back(move(newA));

但是,即使我的基类被破坏了,valgrind还是说我的工厂方法泄漏了吗?

2 个答案:

答案 0 :(得分:3)

问题是您不应指定std::shared_ptr的参数为指针,即隐式

所以您的声明需要更像这样:

class Fing
{
public:
    Fing(std::string const&) {}
    virtual ~Fing() {}
};

class A: public Fing { public: A(std::string const& s): Fing(s) {}};
class B: public Fing { public: B(std::string const& s): Fing(s) {}};
class C: public Fing { public: C(std::string const& s): Fing(s) {}};

std::vector<std::shared_ptr<Fing>> files;

std::shared_ptr<Fing> create(const std::string &filepath)
{
    return std::make_shared<A>(filepath);
}

答案 1 :(得分:1)

std::shared_ptr是一个智能指针,它为您内部保存一个指针,并管理其生命周期。但是您滥用std::shared_ptr。您永远不要将其T模板参数设置为指针类型,而只能设置为它应指向的实际类型。指向指针会破坏使用智能指针的目的。

您也滥用std::make_shared()。使用std::make_shared()的全部目的是避免显式使用new,并且比单独使用std::shared_ptr<T>可以更有效地分配初始newstd::make_shared()分配您指定的T,并将自己的参数转发给T的构造函数。

动态地自己分配一个指针,然后创建一个std::shared_ptr,它具有自己的动态分配的指针,该指针是指针的副本,这是毫无用处的。

尝试以下方法:

std::vector<std::shared_ptr<Fing>> files;

...

std::shared_ptr<Fing> Fing::create(const std::string &fileType, const std::string &filepath)
{
    if (fileType == "a"s){
        return make_shared<A>(filepath);
    }
    if (fileType == "b"s){
        return make_shared<B>(filepath);
    }
    return make_shared<C>(filepath);
}

...

auto newA = Fing::create("a", "path here");
myfiles.push_back(std::move(newA));

or just:

myfiles.push_back(Fing::create("a","path here"));