segfault奇案 我在C++程序中遇到了一个奇怪的SeFabug案例。我能够在一个小代码中重现它,但不明白为什么会发生。代码如下:

segfault奇案 我在C++程序中遇到了一个奇怪的SeFabug案例。我能够在一个小代码中重现它,但不明白为什么会发生。代码如下:,c++,segmentation-fault,C++,Segmentation Fault,a.hpp: #pragma once #include <boost/shared_ptr.hpp> #include "b.hpp" class A { public: explicit A (); private: std::string str1_; B b_; std::string str2_; }; typedef boost::shared_ptr< A > A_p

a.hpp

#pragma once
#include <boost/shared_ptr.hpp>
#include "b.hpp"

class A
{
    public:
        explicit A ();    
    private:
        std::string str1_;
        B b_;
        std::string str2_;
};

typedef boost::shared_ptr< A > A_ptr;
% make
g++ -Wall -Wextra -g -fno-inline -O0   -c -o main.o main.cpp
g++ -Wall -Wextra -g -fno-inline -O0   -c -o a.o a.cpp
g++ -Wall -Wextra -g -fno-inline -O0   -c -o b.o b.cpp
g++  -o main main.o a.o b.o 
dsymutil main
b.hpp

#include "a.hpp"
A::A () {}
#pragma once
#include <string>

class B
{   
    public:
        B ();
    private:
        std::string str1_;
};   
#include "b.hpp"    
B::B () {}
#include "a.hpp"

int main ()
{
    A_ptr a( new A() );
}
main.cpp

#include "a.hpp"
A::A () {}
#pragma once
#include <string>

class B
{   
    public:
        B ();
    private:
        std::string str1_;
};   
#include "b.hpp"    
B::B () {}
#include "a.hpp"

int main ()
{
    A_ptr a( new A() );
}
make的输出

#pragma once
#include <boost/shared_ptr.hpp>
#include "b.hpp"

class A
{
    public:
        explicit A ();    
    private:
        std::string str1_;
        B b_;
        std::string str2_;
};

typedef boost::shared_ptr< A > A_ptr;
% make
g++ -Wall -Wextra -g -fno-inline -O0   -c -o main.o main.cpp
g++ -Wall -Wextra -g -fno-inline -O0   -c -o a.o a.cpp
g++ -Wall -Wextra -g -fno-inline -O0   -c -o b.o b.cpp
g++  -o main main.o a.o b.o 
dsymutil main
现在运行良好。我从
a.hpp
中删除
B\u
(声明
B\u
),保存
a.cpp
(以触发生成)并再次运行
make

% make
g++ -Wall -Wextra -g -fno-inline -O0   -c -o a.o a.cpp
g++  -o main main.o a.o b.o 
dsymutil main
现在,用以下方法对故障进行编程:

(gdb) bt
#0  0x00007fff97f106e5 in std::string::_Rep::_M_dispose ()
#1  0x00007fff97f10740 in std::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string ()
#2  0x0000000100001091 in A::~A (this=0x1001008b0) at a.hpp:8
#3  0x00000001000011da in boost::checked_delete<A> (x=0x1001008b0) at checked_delete.hpp:34
#4  0x0000000100001026 in boost::detail::sp_counted_impl_p<A>::dispose (this=0x1001008d0) at sp_counted_impl.hpp:78
#5  0x0000000100000d9a in boost::detail::sp_counted_base::release (this=0x1001008d0) at sp_counted_base_gcc_x86.hpp:145
#6  0x0000000100000dd4 in boost::detail::shared_count::~shared_count (this=0x7fff5fbff568) at shared_count.hpp:305
#7  0x0000000100000f2b in boost::shared_ptr<A>::~shared_ptr (this=0x7fff5fbff560) at shared_ptr.hpp:159
#8  0x0000000100000aac in main () at main.cpp:5
(gdb)bt
#std::字符串中的0 0x00007fff97f106e5::_Rep::_M_dispose()
#std::basic_字符串中的1 0x00007fff97f10740::~basic_字符串()
#2 0x0000000100001091位于A::~A(此=0x1001008b0)的A.hpp:8处
#boost中的3 0x00000001000011da::已选中删除(x=0x1001008b0)已选中删除。hpp:34
#boost中的4 0x0000000100001026::detail::sp_counted_impl_p::在sp_counted_impl.hpp处处置(此=0x1001008d0):78
#boost中的5 0x0000000100000d9a::detail::sp_counted_base::在sp_counted_base_gcc_x86处发布(此=0x1001008d0)。hpp:145
#boost中的6 0x0000000100000dd4::detail::shared_count::~shared_count(此值=0x7fff5fbff568)位于shared_count处。hpp:305
#boost::shared_ptr::~shared_ptr(this=0x7fff5fbff560)中的0x0000000100000f2b位于shared_ptr。hpp:159
#main()中的8 0x0000000100000aac位于main.cpp:5

如果我
make clean
make
,则程序运行时不会出现故障。请帮助我理解,如果类中的成员被删除,而项目是在没有清理的情况下生成的,那么为什么程序会出错。

在第二次运行
make

% make
g++ -Wall -Wextra -g -fno-inline -O0   -c -o a.o a.cpp
g++  -o main main.o a.o b.o 
dsymutil main
您正在重新编译的只是
a.cpp
。 然后链接到上次运行make时生成的其余对象文件。这将使
main.cpp
使用较旧的
class A
(包含在
A.h
中)定义,而
class A
A.o
)的新对象文件将使用较新的定义,从而导致崩溃

(具体地说,新的
class A
具有不同的大小,因此它需要在
main()
中的堆栈上保留的内存不同,其成员变量的配置也不同)

这显然是
Makefile
中存在错误依赖关系的问题

当您运行
makeclean/make
时,所有文件都将使用相同的、正确的
class A
定义,并且一切都将正常运行