无效强制转换导致的堆损坏

Heap Corruption caused by Invalid Casting?

本文关键字:损坏 转换 无效      更新时间:2023-10-16

我有代码:

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循环中的强制转换引起的,如果我使用带符号的char 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;
}

尝试在到达末尾后读取不是问题——在数组的其余部分会得到垃圾,但是可以在末尾处理。

假设您的数组大到足以容纳整个文件会导致缓冲区损坏。缓冲区溢出攻击涉及带有精心制作的错误元数据的图像文件,这是众所周知的。

    在Mozilla
  • Mozilla中的
  • 在MSN Messenger
  • Windows XP中的

不要依赖整个文件内容来匹配计算的缓冲区大小

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字节未读取。