读取尺寸大于200x200 px的png图像时,0x77662D37(ntdll.dll)处出现未处理的异常 我使用LIPPNG读取VisualC++中的PNG文件。当读取尺寸为195x195px或更小的图像时,程序工作正常,但当尺寸更高时,程序崩溃

读取尺寸大于200x200 px的png图像时,0x77662D37(ntdll.dll)处出现未处理的异常 我使用LIPPNG读取VisualC++中的PNG文件。当读取尺寸为195x195px或更小的图像时,程序工作正常,但当尺寸更高时,程序崩溃,c++,visual-c++,unhandled-exception,libpng,C++,Visual C++,Unhandled Exception,Libpng,这是错误消息: myprog.exe中0x77662D37 ntdll.dll处的首次意外异常: 0xC0000005:访问冲突读取位置0xB4BFDDFF。未处理 myprog.exe中0x77662D37 ntdll.dll处出现异常:0xC0000005: 访问冲突读取位置0xB4BFDDFF 下面是代码: bool PngImage::load(void) { png_structp pngPtr(NULL); png_infop infoPtr(NULL); F

这是错误消息:

myprog.exe中0x77662D37 ntdll.dll处的首次意外异常: 0xC0000005:访问冲突读取位置0xB4BFDDFF。未处理 myprog.exe中0x77662D37 ntdll.dll处出现异常:0xC0000005: 访问冲突读取位置0xB4BFDDFF

下面是代码:

bool PngImage::load(void)
{
    png_structp pngPtr(NULL);
    png_infop infoPtr(NULL);
    FILE* fp(NULL);

    png_uint_32 w = 0, h = 0;
    int bit_depth, color_type, interlace_type;

    fp = fopen(fileName_.c_str(), "rb");
    if (!fp)
        return false;

    pngPtr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!pngPtr)
    {
        fclose(fp);
        return false;
    }

    infoPtr = png_create_info_struct(pngPtr);
    if (!infoPtr)
    {
        fclose(fp);
        png_destroy_read_struct(&pngPtr, png_infopp_NULL, png_infopp_NULL);
        return false;
    }

    if (setjmp(png_jmpbuf(pngPtr)))
    {
        png_destroy_read_struct(&pngPtr, &infoPtr, png_infopp_NULL);
        fclose(fp);
        return false;
    }

    png_init_io(pngPtr, fp);

    if (setjmp(png_jmpbuf(pngPtr)))
    {
        png_destroy_read_struct(&pngPtr, &infoPtr, png_infopp_NULL);
        fclose(fp);
        return false;
    }

    png_read_info(pngPtr, infoPtr);

    png_get_IHDR(pngPtr, infoPtr, &w, &h,
        &bit_depth, &color_type, &interlace_type,
        int_p_NULL, int_p_NULL);

    if (setjmp(png_jmpbuf(pngPtr)))
    {
        png_destroy_read_struct(&pngPtr, &infoPtr, png_infopp_NULL);
        fclose(fp);
        return false;
    }

    width_ = static_cast<size_t>(w);
    height_ = static_cast<size_t>(h);

    data_ = new png_bytep[height_];
    for (size_t i = 0; i < height_; ++i)
        data_[i] = new png_byte[width_ * BYTE_PER_PIXEL];

    png_read_image(pngPtr, data_);

    if (setjmp(png_jmpbuf(pngPtr)))
    {
        png_destroy_read_struct(&pngPtr, &infoPtr, png_infopp_NULL);
        fclose(fp);
        for (size_t i = 0; i < height_; ++i)
            delete[] data_[i];
        delete[] data_;
        data_ = NULL;
        width_ = height_ = 0;
        return false;
    }

    png_read_end(pngPtr, infoPtr);

    png_destroy_read_struct(&pngPtr, &infoPtr, png_infopp_NULL);

    fclose(fp);

    return true;
}
代码似乎停止在png\u destroy\u read\u struct&pngPtr,&infoPtr,png\u infopp\u NULL;在fclosefp之前

我收到未处理异常的原因可能是什么?希望你能帮上忙。先谢谢你


PS:我对libpng不太熟悉假设:这段代码假设每个图像都是24位/像素RGB格式

如果读取32位/像素RGBA图像或48位/像素RGB图像,则

data_u[i]=新的png_字节[每像素的宽度_*字节_]

无法为每个扫描行分配足够的字节

C++是一种不安全的语言,当读取这些过短的数组时,缓冲区溢出会破坏堆数据结构,这可能不会触发症状,除非您尝试释放某些内容


此外,在成功的情况下,这段代码似乎忘记释放数组,或者data是一个实例变量,用于将图像保存在内存中?

BTW,我建议始终在for和if子句周围使用大括号。如果你不考虑它们,很容易出错,例如插入一行代码来进行调试日志记录。嗨,jerry!谢谢你的努力。你的假设是对的。我发现我正在读取的图像是32位图像,这导致了问题。很高兴能提供帮助。我不理解“暂停”这个主题,因为这个问题包括所需的行为、特定的错误和相对较短的代码。给出的代码足以解决问题,调用libpng并没有比这简单得多[尽管如果setjmp…{…},它不需要重复这么多]。我对libpng不太熟悉,这是一种有趣的自我惩罚形式。您可能会发现一篇有趣的文章,因为您似乎遗漏了一些内容,如解释交错、验证文件签名、正确的每行大小信息等。。
const size_t BYTE_PER_PIXEL = 3;
const size_t RED_OFFSET = 0;
const size_t GREEN_OFFSET = 1;
const size_t BLUE_OFFSET = 2;
const png_byte BIT_DEPTH = 8;