c++ - g++ 9.2.1 (Linux) 导致段错误,但 Windows 上的代码块不会

标签 c++ file-handling

以下简单代码(二进制文件处理)在与适用于 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 不是?还是我发现了一个错误?

最佳答案

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

您不能按字节序列化像 std::string 这样的复杂对象像那样。

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

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

关于c++ - g++ 9.2.1 (Linux) 导致段错误,但 Windows 上的代码块不会,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59718412/

相关文章:

C语言使用文件操作创建数据库

c++ - 什么时候删除流对象?

c++ - 如何将 vector <cv::Point2d> 转换为 vector <cv::Point>?

c++ - 无限循环的形式不好吗?

java - 导出的桌面应用程序中的内部文件的 LibGDX 列表

java - "' "is converting into "– “将一个文件的内容复制到另一个文件时

c - 用C语言用哪个数据库最方便?

php - 使用 PHP 替换大文件中的字符

c++ - *** 内部错误 : unable to open jobserver semaphore '3,4' : (Error 2: The system cannot find the file specified. )。停止

c++ - VC++ 目录似乎无法在 Visual Studio Community 2013 中设置