我开发了一个小程序,它运行正常,直到我对代码中一些不相关的部分做了一个非常小的改动。从那时起,该程序抛出一个未处理的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时,而不是仅仅在函数内部使用。仍然......没有意义,这不应该发生。
我真的很想知道这里的问题是什么?
老实说,有谁知道这可归因于什么?
答案 0 :(得分:1)
要调查的几点:
firstImageRead
初始化为true
?imgBuffer
有多大,所以进一步处理可能是在缓冲区末尾读取。其余代码如何确定从imgBuffer
读取的数据量?dataSize
大于第一张图片,imgBuffer
将会太小。DATASIZEINBYTES
上看到的字符恰好为负数,则会尝试malloc()
约2GB。旁注:是否正确,您只读取一个字节的图像大小?图像是否小?
答案 1 :(得分:0)
如果您显示失败的异常和callstack将会有所帮助。
我的猜测是存在共享冲突,您在关闭之前再次打开该文件。在您提前退出的情况下,文件未被关闭。
答案 2 :(得分:0)
你确定文件存在并且你正在从流中读取吗?
那个全局'imgBuffer'怎么样,确保在几次调用FileReader :: readBitmap()
之间没有任何东西在调用它您好,感谢您的投入,但是 不幸的是,该文件确实存在 这个缓冲区被释放的唯一时间是 在计划结束时。它必须 是这个功能,因为如果我清空它 并且只是返回true; , 该程序 运行良好...但没有输入(没有 文件阅读)。
确保为缓冲区分配足够的空间。请记住,malloc()仅在您第一次调用此函数时调用。如果dataSize是第一次说1000,如果你在下一个文件中想要读取2000个字节,dataSize将是2000,但缓冲区只分配1000个字节。
答案 3 :(得分:0)
我正在回答我自己的问题,因为我发现了问题所在。正如大多数人猜测的那样,确实指针指数超出界限仅为+1。让我们很难发现的是调试器向我指出了一个完全不同的方向。
这也解释了为什么在类中添加一个私有成员'修复'了这个问题。它为fileReader对象分配了更多的内存,并且在附加的私有成员占用的内存上写出了超出范围,并且没有导致未处理的异常。
我们从这一切中学到了什么?在设置索引时要非常小心....因为这不是第一次发生在我身上:)