【问题标题】:ifstream is crashing on x64 bit platformifstream 在 x64 位平台上崩溃
【发布时间】:2020-08-27 00:36:02
【问题描述】:

我正在尝试使用 ifstream 打开一个 txt 文件并使用 ifstream 从该文件中读取数据,而该代码在 x86 位平台上运行良好,在 x64 位平台上使用它会导致奇怪的应用程序崩溃.

ifstream font;

font.open(filename);
if ( font.fail() )
{
    return false;
}

// Used to read 95 ASCII characters in the text file
for ( int i = 0; i < 95; i++ )
{
        font.get(temp);
        while (temp != ' ')
        {
            font.get(temp);
        }

        font.get(temp);
        while (temp != ' ')
        {
            font.get(temp);
        }

        font >> m_Font[i].left;
        font >> m_Font[i].right;

        font >> m_Font[i].size;
}

删除font.fail()检查会导致程序卡在font.get(temp);,这意味着font.fail()导致程序崩溃,如果有人知道这个问题的解决方案或者可以指出另一种阅读方式在这种情况下的文本文件,请告诉我。

可以在下面找到可重现的示例,请确保将构建配置设置为 x64 并将子系统设置为 Windows`

#include <Windows.h>
#include <iostream>
#include <fstream>

using namespace std;

struct TestStruct
{
    int test;
}; TestStruct* testStruct;

bool Test(char* filename)
{
    testStruct = new TestStruct[8];
    if (!testStruct)
    {
        return false;
    }

    ifstream font;
    font.open(filename);
    if (font.fail())
    {
        return false;
    }

    char temp;

    for ( int i = 0; i < 8; i++)
    {
        font.get(temp);
        while (temp != ' ')
        {
            font.get(temp);
        }

        font.get(temp);
        while (temp != ' ')
        {
            font.get(temp);
        }

        font >> testStruct[i].test;
    }

    font.close();

    return true;
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR pScmdline, int iCmdshow)
{
    AllocConsole();
    freopen("CONOUT$", "w", stdout);
    
    while ( Test((char*)"test.txt") )
    {
    }

    return 0;
}

P.S 我在从构建文件夹执行二进制文件时无法重现此问题,但是在附加本地 Windows 调试器的情况下启动它时仍然会发生。

【问题讨论】:

  • font.fail 真的crash,还是这个函数return false 然后出现其他问题?
  • 请发帖minimal reproducible example。它应该编译并重现您的问题。
  • m_Fonttemp 是如何声明的?
  • 当您使用调试器运行程序时,您看到了什么?这正是调试器的用途。如果您不知道如何使用调试器,这是一个学习如何使用它来一次运行您的程序、监控所有变量及其值的变化以及分析程序的逻辑执行流程的好机会。知道如何使用调试器是每个 C++ 开发人员必备的技能,没有例外。在调试器的帮助下,您应该能够快速找到此程序以及您编写的所有未来程序中的所有错误,而无需向任何人寻求帮助。
  • 为什么不使用bool Test(const char* filename)?像这样(char*)"test.txt") 调用 UB

标签: c++ file 64-bit ifstream


【解决方案1】:

您有一个无限循环,它使用相同的参数调用相同的函数。此函数执行完全相同的过程,但具有创建TestStruct 数组的副作用。

当一切“正常”时,该函数返回 true,并再次调用。一个问题是您永远不会删除您在函数内部动态创建的数组。这意味着迟早你会耗尽内存,并且这个无限循环会被打破。但它不会以您计划的方式被破坏:operator new(您正在使用的那个)会抛出异常(std::bad_alloc)而不是返回nullptr

这就是我从您的代码中看到的。编译器可能会看到相同的结果,它可以以许多奇怪的方式优化代码以实现相同的行为。尝试纠正导致UB和内存泄漏的问题,也许编译器会改变主意。

【讨论】:

    【解决方案2】:

    正如一些人指出的那样,从一种字符串类型转换为另一种类型,在这种情况下,从 const char*char* 会导致未定义的行为,起初我在可重现的示例中修复了它,但无法修复它我的主要项目,但是在将所有字符串类型更改为原始函数正在使用的字符串类型之后,它解决了问题,即:

    D3DX11CreateShaderResourceViewFromFile 正在使用 LPCTSTR 并在我尝试从 WCHAR* 投射 LPCTSTR 时导致崩溃

    【讨论】:

    • 我的建议是,如果您必须将指针转换为字符串类型,您很可能会犯错,因为转换不会转换指向其他类型的数据,它只会使编译器静音。跨度>
    • LPCTSTR 表示指向常量字符串的长指针,即const char*。你为什么要将wchar_t* 传递给const char*
    猜你喜欢
    • 1970-01-01
    • 2013-05-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-26
    • 1970-01-01
    相关资源
    最近更新 更多