C++德克投掷赛格错误

C++ deque throwing Segfaults

本文关键字:错误 德克 C++      更新时间:2023-10-16

我有一些来自一个似乎不起作用的项目的代码。

我正在尝试制作一个双端(结构体(,它是类的静态成员。骨架/基本代码如下(我保留了所有数据类型 - my_typedef_fn是通过类型定义函数指针获得的数据类型(:

1.h 文件 :

class A {
    struct Bstruct {
        char * b_name;
        my_typedef_fn b_func;
    }
    static std::deque<Bstruct> a_deque;
    static void func();
}

1.cpp文件 :

std::deque<A::Bstruct> A::a_deque;
void A::func(char * name, my_typedef_fn fn) {
    a_deque.push_front((Bstruct) {name, fn} ); // <<<< segfault !
} 

据我了解 - .h文件只是声明东西(像往常一样( - .cpp中的第一行初始化静态成员a_deque - 函数 func 使用 push_back 将内容添加到双端面

但是我在调用push_front的行收到分段错误(使用 gdb 找到这个(。

另外,当我在push_front之前打印a_deque.size((时,我在SEGFAULT之前4294967264当我使用 for 循环计算 deque 中的元素数量时:

int counter = 0
for( std::deque<Bstruct> it = a_deque.begin(); it != a_deque.end(); it++, counter++ );

我的计数器显示 0 个元素在

所以,我不明白为什么

我得到一个段错误,也不明白为什么 .size(( 是一个大的垃圾数

--

编辑 1 --添加调用函数的方式:

2.cpp

#include "1.h"
void fn1() { 
    // some code
}
A::func("abc", fn1);

它符合以下命令:

g++ -c -w -fpermissive -o 1.o 1.cpp
g++ -c -w -fpermissive -o 2.o 2.cpp
g++ -o final 1.o 2.o

通常不可能简单地在全局范围内调用函数,就像您在 2.cpp 中显示的那样。但是你提到代码很旧,所以也许它是一个预先标准的东西,或者一个扩展。

无论如何,您已经展示了该函数在 2.cpp 中被调用,而静态数据成员a_deque是在 1.cpp 中定义的。这意味着您可能正在成为静态初始化顺序惨败的牺牲品。全局变量(例如静态数据成员,显然还有这个奇怪的独立函数调用(按照它们出现在一个翻译单元(= .cpp 文件(中的顺序进行初始化/执行,但它们在翻译单元中的顺序是未指定的。

这意味着A::func()完全有可能在a_deque的构造函数运行之前访问a_deque,这很可能导致段错误(因为 deque 的内部数据成员具有零甚至随机值(。

要解决此问题,您必须以某种方式摆脱这种情况。一种选择是将所有可以访问a_deque的全局代码移动到1.cpp中,并将其放在a_deque的定义之后。

另一种方法是将a_deque替换为函数范围的静态变量,该变量保证在首次使用之前初始化:

1.小时

class A {
    struct Bstruct {
        char * b_name;
        my_typedef_fn b_func;
    }
    static std::deque<BStruct>& a_deque();
    static void func();
}

1.cpp

#include "1.h"
std::deque<A::BStruct>& A::a_deque()
{
  static std::deque<BStruct> d;
  return d;
}
void A::func(char * name, my_typedef_fn fn) {
    a_deque().push_front((Bstruct) {name, fn} ); // <<<< hopefully no more segfault
}