由于具有循环引用的类中的unique_ptr或vector而导致核心转储

时间:2019-05-29 21:05:54

标签: c++ vector unique-ptr coredump cyclic-reference

我正在尝试使用带有循环引用类的代码来处理。当我尝试将其定义为类成员时,我发现unique_ptr或vector出现问题。

此代码包含3个类。为了避免任何歧义,我将展示所有这些内容。

首先,我通过main.cpp中称为启动的类来启动代码:

#include <memory>
#include <vector>
#include "startup.h"
#include "Derived_B.h"
int main() {
    std::unique_ptr<startup> go(new startup);
    return 0;
}

在启动类中,声明了派生类(请注意基类不在此类中):

//Header file
#include <memory>
class startup {
public:
    startup();
    ~startup();
    class Derived_B *dcb;
};
//.cpp
#include "startup.h"
#include "Derived_B.h"
startup::startup() {
    dcb = new Derived_B(this);
}
startup::~startup() {
delete dcb;
}

在显示派生类之前,我将显示基类:

//Header file    
#include "startup.h"
class Base {
public:
    class startup *go;
    class Derived_B *&dcb;
    Base(startup *up):go(up),
                      dcb(up->dcb){}
    ~Base(){}
};

现在,派生类为:

//Header file    
#include <memory>
#include <vector>
#include "Base.h"
class Derived_B:public Base {
public:
    Derived_B(startup *up);
    ~Derived_B(){}
    std::unique_ptr<double[]> apple; //Unique pointer here may give problem
    std::unique_ptr<double[]> apple2; //Unique pointer here may give problem
    std::vector<double> orange; //Vector here may give problem too
};
//.cpp
#include "Derived_B.h"
Derived_B::Derived_B(startup *up):Base(up) {

}

我以这种方式构造了这些类,以便让启动类和Derived_B类直接了解每个其他人的公共成员。但是,在Derived_B类中添加unique_ptr或vector之后,有时我会遇到核心转储的问题。

我已经用valgrind检查了,结果在这里:

==7999== 1 errors in context 1 of 2:
==7999== Invalid write of size 8
==7999==    at 0x400967: _Vector_impl (stl_vector.h:87)
==7999==    by 0x400967: _Vector_base (stl_vector.h:125)
==7999==    by 0x400967: vector (stl_vector.h:257)
==7999==    by 0x400967: Derived_B::Derived_B(startup*) (Derived_B.cpp:7)
==7999==    by 0x4008F0: startup::startup() (startup.cpp:11)
==7999==    by 0x40076A: main (main.cpp:9)
==7999==  Address 0x5ab6d00 is 8 bytes after a block of size 40 alloc'd
==7999==    at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7999==    by 0x4008E2: startup::startup() (startup.cpp:11)
==7999==    by 0x40076A: main (main.cpp:9)
==7999== 
==7999== 
==7999== 1 errors in context 2 of 2:
==7999== Invalid write of size 8
==7999==    at 0x40095F: _Vector_impl (stl_vector.h:87)
==7999==    by 0x40095F: _Vector_base (stl_vector.h:125)
==7999==    by 0x40095F: vector (stl_vector.h:257)
==7999==    by 0x40095F: Derived_B::Derived_B(startup*) (Derived_B.cpp:7)
==7999==    by 0x4008F0: startup::startup() (startup.cpp:11)
==7999==    by 0x40076A: main (main.cpp:9)
==7999==  Address 0x5ab6cf8 is 0 bytes after a block of size 40 alloc'd
==7999==    at 0x4C2E0EF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7999==    by 0x4008E2: startup::startup() (startup.cpp:11)
==7999==    by 0x40076A: main (main.cpp:9)
==7999== 
==7999== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

请注意,问题是随机发生的,有时valgrind会报告有问题的unique_ptr。 有人可以告诉我如何解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

您正在通过使两个对象相互引用来创建循环引用,因此您不应使用唯一的指针。尝试使用弱指针。

How to break shared_ptr cyclic reference using weak_ptr