调试断言失败

Posted

技术标签:

【中文标题】调试断言失败【英文标题】:Debug Assertion Failed 【发布时间】:2011-07-18 13:56:40 【问题描述】:

使用 Visual Studio 2010、C++。 编程水平:初学者。

我有一本 Windows Game Programming Gurus 一书中的代码,到目前为止,我已经解决了我偶然发现的所有问题。

但我不知道它是什么。

这是一个错误的截图:

那是一张不错的 8 位图像...

现在,它显示 File: f:\dd...

在我的情况下 f: drive is empty cd-rom...

这是我认为发生错误的行:

_lseek(file_handle, -((int) (bitmap->bitmapinfoheader.biSizeImage)), SEEK_END);   

这是什么东西?

【问题讨论】:

如果您处于调试状态,请按重试,然后查看调用堆栈以找到您的代码,然后依次调用 _lseek 此代码中的一个函数调用_lseek,这是有意的。调用堆栈在 _lseek 处停止。 【参考方案1】:

f:\dd 目录是“C 运行时库”(CRT) 的源代码所在的位置,在构建时。由于 Microsoft 构建了它,它与您的 F: 驱动器不对应。

无论如何,CRT 检测到其中一个文件句柄有误。你把它传递给了 CRT,所以你应该检查它为什么错了。如果您按下 Retry,您将被放入调试器。在那里你可以看到你的哪些函数放入了错误的文件句柄。

它不会告诉你为什么句柄是错误的。一个常见的原因是您试图打开一个文件,却忘记检查它是否成功。只有当文件名有效时,您才会获得文件句柄,并且您可以读取该文件。

【讨论】:

我照你说的做了。文件句柄始终是 268。如果这意味着什么。调用堆栈转到 _lseek 函数。 我在 devcpp 中尝试过相同的功能,没有其余代码,file_handle 得到 36,但 _lseek 返回 -1L...我猜 .bmp 文件的某些内容是错误的。该怎么办? ...【参考方案2】:

断言发生在 C 库中。它确保您将有效参数传递给lseek() 函数。

对文件执行open()creat() 后,您可能没有检查错误。

【讨论】:

【参考方案3】:

看起来你的 file_handle 是错误的。你确定你的图片打开成功了吗?

【讨论】:

您使用什么代码打开文件?你确定你的图片路径没问题? 该文件与源文件一起在项目文件夹中。 if (!Load_Bitmap_File(&bitmap, "bitmap24.bmp")) return(0);函数 Load_Bitmap_File 调用 OpenFile()。 Load_Bitmap_File 原型:int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename); 您的图像文件在源文件所在的文件夹中吗?但是你的可执行文件在哪里?当您使用 VS 启动它时,工作目录是什么?不确定您的错误是否在这里,但确保您的开放作品将消除这种可能性。顺便问一下,Load_Bitmap_File 是你写的函数吗?因为我看不到你从哪里得到 OpenFile 返回的句柄。 不,Load_Bitmap_Handle 来自我正在阅读的书。可执行文件:d:\C\Visual Studio\Windows Game Programming Gurus\CHAPTER_07\DEMO7_11\Debug\ 位图和来源:d:\C\Visual Studio\Windows Game Programming Gurus\CHAPTER_07\DEMO7_11\DEMO7_11\ Whole thing with open/read /seek/close 在 Load_Bitmap_File 函数中。我还尝试使用 _sopen_s 打开文件,但即使包含 io.h 标头和所有必需的标头,devcpp 也拒绝定位函数。 Visual Studio 中的工作目录呢?它是否设置为 $(ProjectDir) 之类的东西?还是 $(OutDir) ?或者是其他东西 ?您可以通过右键单击项目名称 -> 属性 -> 调试 -> 工作目录来检查这一点【参考方案4】:

使用 C++ ifstream 代替低级 IO 函数的完整函数代码。 乔纳森和我试图让_lseek 工作只是得出结论它不起作用...... 不知道这是否完全正确,也许有某种方法可以正常工作。 如果您(读者)知道,请随时给我发消息。 该功能现在可以工作了,虽然主程序显示图像错误,但除了这个问题之外,_lseek 事情已经解决了:)

int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename)   
   
    int file_handle = 0;        // the file handle
    int index = 0;                  // looping index   
    int bitmapWidth = 0;
    int bitmapHeight = 0;
    int bitmapSize = 0;
    UCHAR *temp_buffer = NULL; // used to convert 24 bit images to 16 bit   
    streampos pos_cur;

    ifstream bitmapFile = ifstream ();
    bitmapFile.open (filename, ifstream::in);
    if (! bitmapFile.is_open ())
    
    printError ("Error: OpenFile function failure. ");

        // abort
        return(0);
    


    // load the bitmap file header:   
    //_lread(file_handle, &(bitmap->bitmapfileheader), sizeof(BITMAPFILEHEADER)); 
    bitmapFile.read ((char *) &(bitmap->bitmapfileheader), sizeof (BITMAPFILEHEADER));

    // test if this is a bitmap file   
    if (bitmap->bitmapfileheader.bfType != BITMAP_ID)   
       
        // close the file   
        //_lclose(file_handle);   
        bitmapFile.close ();
        printError ("error: wrong bitmap type");
        cout << "error: wrong bitmap type" << endl;
        // return error   
        return(0);   
     // end if   

    // now we know this is a bitmap, so read in all the sections.   
    if (bitmap->bitmapinfoheader.biSizeImage == 0)
    printError ("error: biSizeImage equals 0");


    // now the bitmap infoheader:   

    //_lread(file_handle, &bitmap->bitmapinfoheader, sizeof(BITMAPINFOHEADER));   
    bitmapFile.seekg (sizeof (BITMAPFILEHEADER), ios::beg);
    pos_cur = bitmapFile.tellg (); // save current stream position
    bitmapFile.read ((char *) &(bitmap->bitmapinfoheader), sizeof (BITMAPINFOHEADER));

    //cout << bitmap->bitmapinfoheader.biBitCount << endl;


    // now load the color palette if there is one   
    if (bitmap->bitmapinfoheader.biBitCount == 8)   
       
        //_lread(file_handle, &bitmap->palette, MAX_COLORS_PALETTE * sizeof(PALETTEENTRY));   
        // not tested: 
        bitmapFile.read ((char *) &(bitmap->palette), MAX_COLORS_PALETTE * sizeof(PALETTEENTRY)); 

        // now set all the flags in the palette correctly and fix the reversed    
        // BGR RGBQUAD data format   
        for (index = 0; index < MAX_COLORS_PALETTE; index++)   
           
            // reverse the red and green fields   
            int temp_color                = bitmap->palette[index].peRed;   
            bitmap->palette[index].peRed  = bitmap->palette[index].peBlue;   
            bitmap->palette[index].peBlue = temp_color;   

            // always set the flags word to this   
            bitmap->palette[index].peFlags = PC_NOCOLLAPSE;   
         // end for index   

     // end if   

    bitmapWidth = bitmap->bitmapinfoheader.biWidth * (bitmap->bitmapinfoheader.biBitCount / 8);
    bitmapHeight = bitmap->bitmapinfoheader.biHeight; 
    bitmapSize = bitmapWidth * bitmapHeight;


    // finally the image data itself:  
    //_lseek(file_handle, -((int) (bitmap->bitmapinfoheader.biSizeImage)), SEEK_END);
    bitmapFile.seekg (-((int) bitmapSize), ios::end);
    //bitmapFile.seekg (sizeof (BITMAPINFOHEADER) + sizeof (BITMAPFILEHEADER) + MAX_COLORS_PALETTE * sizeof(PALETTEENTRY), ios::beg);

    // now read in the image, if the image is 8 or 16 bit then simply read it   
    // but if its 24 bit then read it into a temporary area and then convert   
    // it to a 16 bit image   

    if (bitmap->bitmapinfoheader.biBitCount == 8  || 
         bitmap->bitmapinfoheader.biBitCount == 16 ||    
         bitmap->bitmapinfoheader.biBitCount == 24)   
       
        // delete the last image if there was one   
        if (bitmap->buffer)   
            free(bitmap->buffer);   

        // allocate the memory for the image   
        //if (!(bitmap->buffer = (UCHAR *) malloc (bitmap->bitmapinfoheader.biSizeImage))) // error: biSizeImage == 0 !
        if (!(bitmap->buffer = (UCHAR *) malloc (bitmapSize)))
           
            // close the file   
            //_lclose(file_handle);   
            bitmapFile.close ();

            // return error   
            return(0);   
         // end if   

        // now read it in   
        //_lread(file_handle, bitmap->buffer, bitmap->bitmapinfoheader.biSizeImage);  
        bitmapFile.read ((char *) (bitmap->buffer), bitmapSize);

     // end if   
    else   
       
        // serious problem   
        return(0);   

     // end else   


    // close the file   
    //_lclose(file_handle);  
    bitmapFile.close ();

    // flip the bitmap   

    Flip_Bitmap(bitmap->buffer,    
                    bitmap->bitmapinfoheader.biWidth * (bitmap->bitmapinfoheader.biBitCount / 8),
                    bitmap->bitmapinfoheader.biHeight);   
    //cout << "biSizeImage: " << bitmap->bitmapinfoheader.biSizeImage << endl;
    //cout << (bitmap->bitmapinfoheader.biWidth * (bitmap->bitmapinfoheader.biBitCount / 8)) * bitmap->bitmapinfoheader.biHeight << endl;

    // return success   
    return(1);   

 // end Load_Bitmap_File   

///////////////////////////////////////////////////////////   

当前完整源代码: http://pastebin.com/QQ6fMD7P 过期日期设置为从不。

感谢所有为这个问题做出贡献的人!

【讨论】:

【参考方案5】:

lseek 因调试断言失败错误而崩溃,因为它是一个 16 位函数。我通过查看 microsoft 网站上的 16 位和 32 位函数图表发现了这一点。

解决方案是使用 _llseek。 _llseek 是 32 位函数,可以在 64 位计算机上运行。 您无需更改 _lseek 的任何参数即可使用 _llseek。

_lseek(file_handle, -((int) (bitmap->bitmapinfoheader.biSizeImage)), SEEK_END); 

变成

_llseek(file_handle, -((int) (bitmap->bitmapinfoheader.biSizeImage)), SEEK_END); 

【讨论】:

以上是关于调试断言失败的主要内容,如果未能解决你的问题,请参考以下文章

调试断言失败:_CrtIsValidHeapPointer(pUserData)

调试断言失败,向量下标超出范围

c++错误:调试断言失败

调试断言失败

没有堆栈时如何调试iOS断言失败崩溃

sprintf_s() 因“调试断言失败”错误而失败