gpt4 book ai didi

c++ - 从静态变量引用非静态变量会使非静态变量在静态变量之前析构

转载 作者:行者123 更新时间:2023-11-28 02:09:19 25 4
gpt4 key购买 nike

简单地说:我想在我的程序退出时写入一个文件,所以我有一个接受文件名 (char*) 和对 Google Protobuf 消息的引用的对象(出于这些目的,您可以假装它是string&) 在构造函数中,然后将消息写入析构函数中的文件名。然后,在 main() 中,我初始化了其中一个对象并将其声明为静态的(因此当程序出于任何原因退出时它将被破坏)。

在我更改(看似)不相关的内容之前,我的代码在多次修订后一直运行良好,但现在它不起作用了。现在,当对象析构时,char* 和引用都指向 char 和 Message 的未初始化版本。我有下面的相关代码:

using namespace std;

class WriteOnShutdown {
private:
const char* filename;
public:
MathHelper::Log& message;

WriteOnShutdown(char* a, MathHelper::Log& b) : filename(a), message(b) {}
~WriteOnShutdown() {
cout << "debug\n";
//*filename is -52 (unitialised char)
//READ ACCESS VIOLATION - message is still valid, but message.DebugString tries to call a pointer which hasn't been initialised yet
cout << message.DebugString() << endl;
}
};

int main() {
char filename[100];
MathHelper::Log log;

//Initialise filename and log

static WriteOnShutdown write(filename, log);

//Do program stuff here

//Then, at the end of main(), printing write.message.DebugString() works like a charm
cout << endl << write.message.DebugString();
_getch();
}

最佳答案

您遇到问题的原因如下:

MathHelper::Log log 将在您的主要返回之前 被销毁,但是WriteOnShutdown 的析构函数将在之后被调用 主要返回。

由于 WriteOnShutdown 在析构函数中使用了对 log 的引用,因此您正在访问“悬空”引用,调用未定义的行为,因此会发现问题所在。

filename 也有同样的问题。

明显的解决方法是将 write(顺便说一句,由于多种原因,它是一个糟糕的对象名称)从静态更改为自动变量。

关于c++ - 从静态变量引用非静态变量会使非静态变量在静态变量之前析构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36317010/

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