使用我的共享指针获取内存泄漏?

问题描述 投票:-2回答:2

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

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说我的工厂方法有漏洞吗?

c++ memory memory-management memory-leaks
2个回答
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
投票

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

你也在滥用std::make_shared()。使用std::make_shared()的重点是避免必须明确使用new,并更有效地分配初始std::shared_ptr<T>然后使用new本身就可以。 std::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"));
© www.soinside.com 2019 - 2024. All rights reserved.