真正及时调试和文件流的奇怪问题

时间:2009-06-08 22:20:22

标签: c++ debugging filestream

我开发了一个小程序,它运行正常,直到我对代码中一些不相关的部分做了一个非常小的改动。从那时起,该程序抛出一个未处理的win32异常和Microsoft Visual Studio及时调试器启动。

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

由于我无法使用gdb进行调试以查看错误(因为它在调试模式下运行正常),因此我将pr​​intfs放在此处以找到它的根。我在一个函数中分离但它没有意义。

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 个答案:

答案 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对象分配了更多的内存,并且在附加的私有成员占用的内存上写出了超出范围,并且没有导致未处理的异常。

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