Определение алмазных объектов - PullRequest
1 голос
/ 31 марта 2020

Предполагая, что у меня есть алмазная иерархия, как показано в приведенном ниже коде.

class A {

public:
    A() {}
    int a = 3;
    virtual void aa() {}
};

class B : public virtual A {
public:
    B() : A() {}

    int b() { return 4; };
};

class C : public virtual A {
public:
    C() : A() {}
};

class D : public B, public C {
protected:
    int d = 45;

public:
    D() : B(), C() {}
};

У меня есть основная такая:

int main() {
    std::unique_ptr<A> a = std::make_unique<D>();
}

Приведенная выше основная приводит к ошибке сегментации. Однако добавление a.release() к основным обслуживает ошибку сегментации. Почему это так?

1 Ответ

1 голос
/ 31 марта 2020

Это потому, что в A. нет виртуального Dtor. Без Dtor вы можете видеть, что при работе с GDB происходит сегрегация при уничтожении объекта:

eddy@eddy-VirtualBox:~/deleteme$ g++ -std=c++14 -O0 -g test.cpp       
eddy@eddy-VirtualBox:~/deleteme$ gdb a.out
(gdb) run
Starting program: /home/eddy/deleteme/a.out 

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff76f2c01 in __GI___libc_free (mem=0x555555769e88) at malloc.c:3123
3123    malloc.c: No such file or directory.
(gdb) bt
#0  0x00007ffff76f2c01 in __GI___libc_free (mem=0x555555769e88) at malloc.c:3123
#1  0x0000555555554f6d in std::default_delete<A>::operator() (this=0x7fffffffddd8, __ptr=0x555555769e88) at /usr/include/c++/7/bits/unique_ptr.h:78
#2  0x0000555555554e07 in std::unique_ptr<A, std::default_delete<A> >::~unique_ptr (this=0x7fffffffddd8, __in_chrg=<optimized out>)
    at /usr/include/c++/7/bits/unique_ptr.h:268
#3  0x0000555555554b68 in main () at test.cpp:33

Добавление виртуального деструктора в исправления класса A это:

public:
    A() {}
    int a = 3;
    virtual void aa() {}
    virtual ~A() = default;
};
...