首页 > 解决方案 > g++ 9.2.1 (Linux) 导致段错误,但 Windows 上的代码块不会

问题描述

以下简单代码(二进制文件处理)在与适用于 Windows 的 Codeblocks 17.12 (mingw32-g++) 捆绑的编译器上运行良好,但在适用于 Linux 的 g++ 9.2.1(在 Ubuntu 19.10 上)出现分段错误:

#include <iostream>
#include <fstream>
using namespace std;
class A {
public:
    int x;
    string y;
};
int main()
{
    ofstream k;
    A m;
    m.x = 10;
    m.y = "Hello";
    k.open("file.dat", ios::binary);
    k.write(reinterpret_cast<char *>(&m), sizeof(A));
    k.close();
    ifstream i;
    A t;
    i.open("file.dat", ios::binary);
    i.seekg(0, ios::beg);
    i.read(reinterpret_cast<char *>(&t), sizeof(A));
    cout << t.x << " " << t.y;
    i.close();
    return 0;
}

我做错了什么吗,Windows 上的最小 g++ 可以原谅我,但 g++-Linux 不是吗?还是我发现了一个错误?

标签: c++file-handling

解决方案


您的程序具有未定义的行为。

你不能像这样按字节序列化一个复杂的对象std::string

未定义行为的结果可能会有所不同;在您的 Linux 安装中,您可能正在目睹“小字符串优化”,其中您的字符串数据小到足以放入一个小的就地缓冲区。这可以避免任何导致 Windows 崩溃的动态内存。也许 Windows 正在检测不良行为,或者它的 SSO 缓冲区较小,或者根本没有!

但是无论哪种方式,代码仍然具有未定义的行为。


推荐阅读