Действительно странная проблема с своевременной отладкой и файловыми потоками - PullRequest
1 голос
/ 09 июня 2009

Я разработал небольшую программу, которая работала нормально, пока я не внес действительно незначительные изменения в какую-то не связанную часть кода. С этого момента программа выдает необработанное исключение 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- EDIT: пытаясь выяснить, в чем может быть проблема, я переместил ifstream из функции в личный член класса. И функция теперь делает ТОЧНО то же самое, только если она использует stream.open (), чтобы открыть файл.

Теперь все работает без проблем. Таким образом, проблема заключается как-то ... в том, что ifstream инициализируется каждый раз внутри функции, а не просто используется внутри функции. Тем не менее ... не имеет смысла, и это не должно было произойти.

Я действительно заинтригован, чтобы выяснить, в чем здесь проблема?

Честно говоря, у кого-нибудь есть идеи, к чему это можно отнести?

Ответы [ 4 ]

1 голос
/ 09 июня 2009

Несколько моментов для исследования:

  • firstImageRead инициализируется true?
  • Остальная часть кода не знает, насколько велика imgBuffer, поэтому дальнейшая обработка, вероятно, читает за пределами буфера. Как остальная часть вашего кода определяет, сколько данных нужно прочитать с imgBuffer?
  • Если dataSize любого изображения больше, чем для первого, imgBuffer будет слишком маленьким.
  • Если символ, который вы прочитали в позиции DATASIZEINBYTES, окажется отрицательным, вы попытаетесь malloc() около 2 ГБ.

Sidenote: Правильно ли, что вы прочитали только один байт для размера изображения? Изображения такие маленькие?

0 голосов
/ 10 июня 2009

Я просто отвечаю на свой вопрос, так как я нашел, в чем проблема. Как и предполагало большинство людей, это действительно был указатель, выходящий за пределы просто +1. Что действительно трудно было заметить, так это то, что отладчик указал мне совершенно другое направление.

Это также объясняет, почему добавление еще одного частного члена в класс «исправило» проблему. Он выделил больше памяти для объекта fileReader, и запись за пределы записывалась в память, занятую дополнительным закрытым элементом, и не вызывала необработанное исключение.

Чему мы учимся из всего этого? Будьте очень, очень осторожны при настройке индексов .... так как это не первый раз, когда это случилось со мной:)

0 голосов
/ 09 июня 2009

Вы уверены, что файл существует и что вы читаете из потока, хорошо?

Как насчет этого глобального imgBuffer, убедитесь, что между несколькими вызовами FileReader :: readBitmap ()

ничего не вызывается бесплатно

Привет и спасибо за ваш вклад, но к сожалению, файл существует и единственный раз, когда этот буфер освобождается в конце программы. Он должен будь эта функция, так как если я опустошу ее и просто верни истину; , программа работает нормально ... но не имеет ввода (нет файл прочитан).

Убедитесь, что вы выделяете достаточно места для буфера. Помните, что malloc () вызывается только при первом вызове этой функции. Если dataSize в первый раз, скажем, 1000, и если в следующем файле вы хотите прочитать 2000 байтов, dataSize будет равен 2000, но буфер будет выделен только для 1000 байтов.

0 голосов
/ 09 июня 2009

Это помогло бы, если бы вы показали исключительную ситуацию и вызов стека при сбое.

Полагаю, было бы нарушение совместного доступа, вы снова открываете файл до его закрытия. В тех случаях, когда вы выходите досрочно, файл не закрывается.

...