0

I am trying to read binary data from a file, here is my file structure:

#define SIGNATURE_LENGTH 3
#define VERSION_LENGTH 2
#define DATACOUNT_LENGTH 4
#define COMPRESS_LENGTH 1
#define FORMAT_LENGTH 2
#define DATALENGTH_LENGTH 4

const unsigned char resSignature[SIGNATURE_LENGTH] = { 0x52, 0x45, 0x53 };
const unsigned char resVersion[VERSION_LENGTH] = { 0x01, 0x00 };

const unsigned char isCompressed[COMPRESS_LENGTH] = { 0x01 };
const unsigned char notCompressed[COMPRESS_LENGTH] = { 0x00 };

// Data Formats:
const unsigned char dataUnknown[FORMAT_LENGTH] = { 0x00, 0x00 };
const unsigned char dataXML[FORMAT_LENGTH] = { 0x01, 0x00 };


// Define header structure for resource file
struct ResHeader
{
    unsigned char signature[SIGNATURE_LENGTH];
    unsigned char version[VERSION_LENGTH];
};

// Define data structure for resource file
struct ResData
{
    unsigned char compressed[COMPRESS_LENGTH];
    unsigned char dataFormat[FORMAT_LENGTH];
    unsigned char dataLength[DATALENGTH_LENGTH];
    unsigned char *data;
};

And my class uses:

std::fstream File;

// Resource file makeup
ResHeader  header;
unsigned char dataCount[DATACOUNT_LENGTH];

// Vector to contain resource file data
std::vector<ResData> ResourceData;

The program crashes when I try to read from a file:

int ResourceFile::LoadFile()
{
    File.open("blah.dat", std::ios::in | std::ios::binary);

    // Read header
    File.read((char*) header.signature, SIGNATURE_LENGTH);
    File.read((char*) header.version, VERSION_LENGTH);
    if(!VerifyHeader())
    {
        File.close();
        return HEADER_INCORRECT;
    }
    File.read((char*) dataCount, DATACOUNT_LENGTH);
    long fileCount = unsignedCharArrayToLong(dataCount);
    for(long i = 0; i < fileCount; ++i)
    {
        ResData tmp;
        File.read((char*) tmp.compressed, COMPRESS_LENGTH);
        File.read((char*) tmp.dataFormat, FORMAT_LENGTH);
        File.read((char*) tmp.dataLength, DATALENGTH_LENGTH);
        File.read((char*) tmp.data, unsignedCharArrayToLong(tmp.dataLength));
        ResourceData.push_back(tmp);
    }
    File.close();
    return SUCCESS;
}

The program crashes on the line:

File.read((char*) tmp.data, unsignedCharArrayToLong(tmp.dataLength));

The length of the data in the file is 282, which is what is read into tmp.dataLength; so the number is accurate. The data is also compressed using easy zlib: http://www.firstobject.com/easy-zlib-c++-xml-compression.htm

Any suggestions/help as to what I am doing wrong or what I could be doing better would be appreciated. Thank you.

4

1 回答 1

2

这个局部变量:

ResData tmp;

包含

unsigned char *data;

鉴于没有任何代码实际上将任何内容分配给data,它将指向内存中的某个“随机”位置。这意味着“未定义的行为”,并且考虑到平均定律和您的结果,在这种情况下,“未定义的行为”意味着您的程序崩溃,这可能比替代方案更好,或者当它出现时您会更加摸不着头脑在其他地方出错了。

你可能想要这样的东西(在阅读 for 之后dataLength):

size_t len = unsignedCharArrayToLong(tmp.dataLength); 

tmp.data = new unsigned char[len];
File.read((char*) tmp.data, len);

稍后,不要忘记释放数据。或者更好的是,使用 a std::vector,而不是对 new 的调用,使用 dodata.resize(len);和 usetmp.data.data()来获取File.read(...). 这样,您就不需要记住释放任何东西,因为std::vector它会为您完成。

于 2013-07-03T20:57:18.913 回答