У меня есть код:
unsigned char *myArray = new unsigned char[40000];
char pixelInfo[3];
int c = 0;
while(!reader.eof()) //reader is a ifstream open to a BMP file
{
reader.read(pixelInfo, 3);
myArray[c] = (unsigned char)pixelInfo[0];
myArray[c + 1] = (unsigned char)pixelInfo[1];
myArray[c + 2] = (unsigned char)pixelInfo[2];
c += 3;
}
reader.close();
delete[] myArray; //I get HEAP CORRUPTION here
После некоторых тестов я обнаружил, что это вызвано приведением в цикле while, если я использую подписанный символ myArray Я не получаю ошибку, но я должен использовать unsigned char для остальной части моего кода.
Преобразование pixelInfo в unsigned char также приводит к той же ошибке.
Есть ли какое-то решение этого?
Вот что вы должны сделать:
reader.read((char*)myArray, myArrayLength); /* note, that isn't (sizeof myArray) */
if (!reader) { /* report error */ }
Если внутри цикла происходит обработка, то
int c = 0;
while (c + 2 < myArraySize) //reader is a ifstream open to a BMP file
{
reader.read(pixelInfo, 3);
myArray[c] = (unsigned char)pixelInfo[0];
myArray[c + 1] = (unsigned char)pixelInfo[1];
myArray[c + 2] = (unsigned char)pixelInfo[2];
c += 3;
}
Попытка чтения после того, как вы дойдете до конца, не является проблемой — вы получите мусор в остальной части массива, но вы можете справиться с этим в конце.
Предполагая, что ваш массив достаточно большой, чтобы вместить весь файл, вызывает повреждение буфера. Атаки переполнения буфера с использованием файлов изображений с тщательно созданными неверными метаданными хорошо известны.
Не полагайтесь на подгонку содержимого всего файла в рассчитанном размере буфера.
reader.eof()
только скажет вам, если предыдущее чтение достигло конца файла, что заставляет вашу последнюю итерацию записывать после конца массива. Вместо этого вам нужно проверить, достигает ли текущее чтение конец файла. Измени свой while
цикл до:
while(reader.read(pixelInfo, 3)) //reader is a ifstream open to a BMP file
{
// ...
}
Обратите внимание, что вы читаете 3 байта за раз. Если общее количество байтов не делится на 3 (не кратно 3), то только часть массива pixelInfo будет заполнена правильными данными, что может привести к ошибке в вашей программе. Вы можете попробовать следующий кусок не испытано код.
while(!reader.eof()) //reader is a ifstream open to a BMP file
{
reader.read(pixelInfo, 3);
for (int i = 0; i < reader.gcount(); i++) {
myArray[c+i] = pixelInfo[i];
}
c += 3;
}
Ваш код очень хорошо следует документации на cplusplus.com, так как бит eof будет установлен после неполного чтения, поэтому этот код завершится после вашего последнего чтения, однако, как я упоминал ранее, вероятной причиной вашей проблемы является тот факт, что вы назначаете вероятные ненужные данные в кучу, так как pixelInfo [x] не обязательно может быть установлен, если не были прочитаны 3 байта.