1

我开发了一个小程序,它运行良好,直到我对代码的一些不相关部分进行了非常小的更改。从那时起,程序将引发未处理的 win32 异常,并且 Microsoft Visual Studio 即时调试器启动。

我正在使用代码块,我的编译器是 gcc 编译器。令人沮丧的是,如果我选择使用 gdb 从代码块进行调试,程序运行良好。这对我来说没有意义。

由于我无法使用 gdb 进行调试以查看问题所在(因为它在调试模式下运行良好),因此我将 printfs 放在此处和此处以查找所有问题的根源。我隔离了一个功能,但这没有任何意义。

bool FileReader::readBitmap(int fileNum)
{
char check;
int dataOffset;
int dataSize;
string fileName;

//used for quick int to string conversion
std::ostringstream stringstream;

stringstream<<fileNum;

string fileNumber = stringstream.str();


fileName = "img"+fileNumber+".bmp";

ifstream stream(fileName.c_str(),ios::in|ios::binary);

stream.read(&check,1);

//checking if it is a bitmap file
if(check != 'B')
    return false;
 stream.read(&check,1);
if(check != 'M')
    return false;

stream.seekg(BMPBPP);
stream.read(&check,1);

//if it is not a monochrome bitmap
if(((int)check) != 1)
    return false;//quit


//get the dataoffset
stream.seekg(DATAOFFSET);
stream.read(&check,1);

dataOffset = (int)check;

//get the data size in bytes
stream.seekg(DATASIZEINBYTES);
stream.read(&check,1);

dataSize = (int)check;

//if this is the first image we read
if(firstImageRead)
{
    //allocate the image buffer
    imgBuffer = (char*) malloc(dataSize);

    //and make sure it does not get re-allocated
    firstImageRead = false;
}


//get the actual bitmap data
stream.seekg(dataOffset);
stream.read(imgBuffer,dataSize);


stream.close();
return true;

}

-BIG- 编辑:试图找出问题所在,我将 ifstream 从函数移到成为类的私有成员。并且该函数现在的功能完全相同,只是它使用 stream.open() 打开文件。

现在它可以正常工作了。所以问题出在不知何故......每次在函数内部初始化ifstream,而不是仅仅在函数内部使用。仍然......没有意义,这不应该发生。

我真的很想知道这里的问题是什么?

老实说,有人知道这可以归因于什么吗?

4

4 回答 4

1

需要调查的几点:

  • firstImageRead初始化true为?
  • 其余代码不知道imgBuffer有多大,因此进一步的处理可能是读取缓冲区末尾之外的内容。您的其余代码如何确定要读取多少数据imgBuffer
  • 如果dataSize任何图像大于第一个,imgBuffer将太小。
  • 如果您在位置读取的字符DATASIZEINBYTES恰好是负数,您将尝试malloc()大约 2GB。

旁注:是否正确,您只读取图像大小的一个字节?图片有那么小吗?

于 2009-06-08T23:07:30.677 回答
0

我只是在回答我自己的问题,因为我发现了问题所在。正如大多数人所猜测的那样,它确实是一个指针索引超出了 +1 的范围。真正难以发现的是调试器将我指向了一个完全不同的方向。

这也解释了为什么在类中添加一个私有成员“修复”了问题。它为 fileReader 对象分配了更多内存,并且越界写入到了附加私有成员占用的内存上,并没有导致未处理的异常。

我们从这一切中学到了什么?设置索引时要非常小心....因为这不是我第一次发生这种情况:)

于 2009-06-10T09:49:44.593 回答
0

如果您显示失败的异常和调用堆栈,这将有所帮助。

我的猜测是存在共享冲突,您在文件关闭之前再次打开文件。在您提前退出的情况下,文件不会被关闭。

于 2009-06-08T22:25:32.243 回答
0

您确定该文件存在并且您正在从流中读取好吗?

那个全局“imgBuffer”怎么样,确保在对 FileReader::readBitmap() 的几次调用之间没有任何空闲调用它

您好,感谢您的输入,但不幸的是该文件确实存在,并且该缓冲区唯一被释放的时间是在程序结束时。它必须是这个函数,因为如果我清空它并返回 true;,程序运行良好......但没有输入(没有文件读取)。

确保为缓冲区分配了足够的空间。请记住, malloc() 仅在您第一次调用此函数时才被调用。如果 dataSize 第一次是 1000,如果你在下一个文件上要读取 2000 字节,dataSize 将为 2000,但缓冲区仅分配 1000 字节。

于 2009-06-08T22:35:24.407 回答