gpt4 book ai didi

c++ - 将未初始化的类实例分配给类指针会导致段错误

转载 作者:行者123 更新时间:2023-11-28 00:30:36 28 4
gpt4 key购买 nike

最近我遇到了我无法理解的奇怪的 C++ 行为。我有一个这样的头文件:

1:  struct LogLevel {
2: public:
3: static const LogLevel ERROR;
4:
5: LogLevel(int id) : _id(id) {}
6:
7: private:
8: int _id;
9: std::string _name;
10: };

然后单独的C++实现文件:

1:  LogLevel l = LogLevel::ERROR;
2: const LogLevel LogLevel::ERROR(1);

第 1 行导致段错误。我知道这与未初始化的内存有关,但我不明白背后发生了什么。

如果您在实现文件中交换第 1 行和第 2 行,则一切正常。

令我非常困惑的是,如果您只是从头文件中注释掉带有 std::string 成员定义的第 9 行,那么一切都还可以。

有没有人有合理的解释?

最佳答案

在同一单元内,静态变量按其定义的顺序进行初始化。

所以当你有这条线时:

LogLevel l = LogLevel::ERROR;

变量 LogLevel::ERROR 尚未运行其构造函数。这会导致未定义的行为。此 UB 将自身显示为段错误的原因可能是因为您按尚未初始化的值复制了 std::string,因此其内部指针将是空指针。

颠倒定义的顺序可以解决问题,因为当您尝试将其分配给 lLogLevel::ERROR 确实存在。

注意。最好使 l static。这可以防止您不小心从另一个单元引用它,从而避免静态初始化顺序 问题。如果您有意要从另一个单元引用它,则必须确保在输入 main() 之前您不会在该单元中访问它。

关于c++ - 将未初始化的类实例分配给类指针会导致段错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23072078/

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