“访问冲突写入位置”与 file.getline ? (仅在发布版本中)

发布于 2024-12-25 02:53:17 字数 1276 浏览 3 评论 0原文

在用 C++ (VS 2010) 编写的应用程序中出现此错误:

divt.exe 中 0x77648da9 处未处理的异常:0xC0000005:访问 违规写入位置 0x00000014。

它指向 free.c 中的这个函数:

void __cdecl _free_base (void * pBlock)
{

        int retval = 0;


        if (pBlock == NULL)
            return;

        RTCCALLBACK(_RTC_Free_hook, (pBlock, 0));

        retval = HeapFree(_crtheap, 0, pBlock);
        if (retval == 0) //<-----------------------right here
        {
            errno = _get_errno_from_oserr(GetLastError());
        }
}

通过调试,我能够确定它实际崩溃的位置:

void MenuState::LoadContentFromFile(char* File,std::string &Content)
{
    std::string strbuf;

    char buffer[1028];

    std::fstream file;
    file.open(File,std::ios_base::in);

    if(file.fail()) 
    {
        Content = ErrorTable->GetString("W0001");
        return;
    }
    if(file.is_open())
    {
        while(!file.eof())
        {
            file.getline(buffer,128,'\n');  // <----here
            strbuf = buffer;
            Content += strbuf + "\n";
        }
    }

    file.close();

    strbuf.clear();
}

它崩溃于 file.getline(buffer,128,'\n');

我不知道理解为什么,但它只在发布版本中执行(优化关闭),在调试版本中它工作正常。

有什么想法吗?

getting this error in an application written in C++ (VS 2010):

Unhandled exception at 0x77648da9 in divt.exe: 0xC0000005: Access
violation writing location 0x00000014.

it points to this function in free.c:

void __cdecl _free_base (void * pBlock)
{

        int retval = 0;


        if (pBlock == NULL)
            return;

        RTCCALLBACK(_RTC_Free_hook, (pBlock, 0));

        retval = HeapFree(_crtheap, 0, pBlock);
        if (retval == 0) //<-----------------------right here
        {
            errno = _get_errno_from_oserr(GetLastError());
        }
}

Via debugging I was able to determine where its actually crashing:

void MenuState::LoadContentFromFile(char* File,std::string &Content)
{
    std::string strbuf;

    char buffer[1028];

    std::fstream file;
    file.open(File,std::ios_base::in);

    if(file.fail()) 
    {
        Content = ErrorTable->GetString("W0001");
        return;
    }
    if(file.is_open())
    {
        while(!file.eof())
        {
            file.getline(buffer,128,'\n');  // <----here
            strbuf = buffer;
            Content += strbuf + "\n";
        }
    }

    file.close();

    strbuf.clear();
}

It crashes on file.getline(buffer,128,'\n');

I don't understand why but it's only doing it in release build (Optimizations turned off), on debug build its working fine.

Any Ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

鹿童谣 2025-01-01 02:53:17

我知道这是一个老问题,但是当您遇到深埋在 free.c 或 xmemory 等文件中的此类问题时,您可能还需要仔细检查您的项目配置。特别是当问题仅涉及某些构建配置时。

例如,在 MSVC 中检查您的项目属性 >配置属性> C/C++>代码生成>运行时库。确保它对于所有依赖项都一致,并且根据当前构建将其设置为调试/发布变体。

I know this is an old question, but when you encounter these sorts of issues buried deep in files such as, free.c or xmemory, you may also want to double check your project configuration. Especially when the issue pertains to only certain build configurations.

For example, in MSVC check your Project Properties > Configuration Properties > C/C++ > Code Generation > Runtime Library. Make sure it consistent for all dependencies and that it is set to a Debug/Release variant depending on the current build.

妄断弥空 2025-01-01 02:53:17

我敢打赌,读取崩溃应用程序之前的读取实际上失败了(尽管我不太确定它为什么会崩溃)。需要注意的重要一点是,eof()有助于确定导致读取失败的原因(并且通常会抑制错误消息)。此外,您总是希望在读取之后检查读取是否成功。最后,我看不出您不直接读取 std::string 的任何原因。总之,尝试使用这个循环:

for (std::string strbuf; std::getline(file, strbuf); ) {
    Content += strbuf;
}

I would bet that the read prior to the read crashing the application actually failed (although I'm not quite sure why it would crash). The important thing to note is that eof() is only good for determining what caused a read failure (and typically suppressing an error message). In addition, you always want to check after the read whether it was successful. Finally, I can't see any reason why you don't read an std::string directly. In summary, try to use this loop instead:

for (std::string strbuf; std::getline(file, strbuf); ) {
    Content += strbuf;
}
铜锣湾横着走 2025-01-01 02:53:17

向朋友寻求帮助,我们想出了这个解决方案:

std::string strbuf;

char buffer[256] = "\0";

FILE* f = fopen(File, "rt");

while(fgets(buffer,sizeof(buffer),f) != NULL)
{
    Content += buffer;
}

fclose(f);
strbuf.clear();

效果很好,仍然感谢您的努力。

Asked a friend for help, we came up with this Solution:

std::string strbuf;

char buffer[256] = "\0";

FILE* f = fopen(File, "rt");

while(fgets(buffer,sizeof(buffer),f) != NULL)
{
    Content += buffer;
}

fclose(f);
strbuf.clear();

Works fine, still thanks for your efforts.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文