gpt4 book ai didi

c++ - 奇怪的段错误案例

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:08:07 25 4
gpt4 key购买 nike

我在 C++ 程序中遇到了一个奇怪的段错误案例。我可以用一小段代码重现它,但不明白为什么会这样。这是代码:

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;

a.cpp

#include "a.hpp"
A::A () {}

b.hpp

#pragma once
#include <string>

class B
{
public:
B ();
private:
std::string str1_;
};

b.cpp

#include "b.hpp"    
B::B () {}

main.cpp

#include "a.hpp"

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

ma​​ke 的输出:

% 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 b_(b_ 的声明),保存 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

如果我 make cleanmake,程序运行时不会出现段错误。请帮助我理解为什么如果删除类中的成员并且在没有清理的情况下构建项目,程序会出现段错误。

最佳答案

在第二次运行 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) 将使用较新的定义,因此会发生崩溃。

(具体来说,new class A的大小不同,所以在main()中需要在栈上预留的内存也不同,其成员的配置也不同变量也不同)。

这显然是您的 Makefile 中的错误依赖项问题。

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

关于c++ - 奇怪的段错误案例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12943383/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com