C++ 智能指针给出 Invalid free, Invalid read

问题描述 投票:0回答:1

测试智能指针——使用 valgrind 运行以下示例给出: 我在 Ubuntu 22.04.1 上使用 g++ 11.3.0:

g++ -g -Wall -o tempa tempa.c

valgrind --leak-check=full --show-leak-kinds=all ./tempa

#include <string> #include <vector> #include <memory> //================ class Jvert { public: Jvert( std::string stgaparm) : stga(stgaparm) {} void addSub( std::shared_ptr<Jvert> jsrc) { // Add jsrc to jsubs std::shared_ptr<Jvert> pthis( this); jsrc->jparent = pthis; jsubs.push_back( jsrc); } std::weak_ptr<Jvert> jparent; std::vector<std::shared_ptr<Jvert>> jsubs; std::string stga; }; // end class Jvert //============== int main( int argc, char * argv[]) { std::shared_ptr<Jvert> jva = std::make_shared<Jvert>("aaa"); std::shared_ptr<Jvert> jvb = std::make_shared<Jvert>("bbb"); jva->addSub( jvb); } //==================

您正在 
c++ smart-pointers
1个回答
4
投票
成员函数中从

this

 的原始指针创建一个 
addSub
std::shared_ptr<Jvert> pthis( this);

这是有问题的,因为当
jva

jvb

 超出 
main
 的范围时,将调用它们的析构函数,这将尝试删除它们持有的原始指针。由于 
this
 用于创建 
pthis
,多个 
shared_ptr
 对象将尝试删除相同的原始指针,导致无效的释放。
要解决此问题,您可以将类更改为继承自 
std::enable_shared_from_this<Jvert>

并使用

shared_from_this()

 获取当前对象的 
shared_ptr
#include <string>
#include <vector>
#include <memory>

class Jvert : public std::enable_shared_from_this<Jvert> {
public:

    Jvert(std::string stgaparm)
    : stga(stgaparm)
    {}

    void addSub(std::shared_ptr<Jvert> jsrc) {
        // Add jsrc to jsubs
        jsrc->jparent = shared_from_this();
        jsubs.push_back(jsrc);
    }

    std::weak_ptr<Jvert> jparent;
    std::vector<std::shared_ptr<Jvert>> jsubs;
    std::string stga;

}; // end class Jvert

int main(int argc, char *argv[]) {

    std::shared_ptr<Jvert> jva = std::make_shared<Jvert>("aaa");
    std::shared_ptr<Jvert> jvb = std::make_shared<Jvert>("bbb");
    jva->addSub(jvb);
}

通过使用
std::enable_shared_from_this
,您可以确保

single shared_ptr

 控制对象的所有权,防止出现无效释放和无效读取的问题。 
C++ 中的智能指针

    

© www.soinside.com 2019 - 2024. All rights reserved.