堆栈变量腐败,不知道是什么问题

时间:2011-06-13 02:37:55

标签: c++ variables stack

问题解决了,谢谢大家的帮助

我在这里遇到了一些问题,这并没有让我的程序爆炸,但是我无法解决这个问题。我有一个函数读取文件中的一些数据,在执行结束时,变量longGarbage周围的堆栈已损坏。我看了一下,发现可能的原因是写入无效的内存。我清理了一些内存泄漏,问题仍然存在。令我感到困惑的是,当函数完成执行时会发生这种情况,因此当变量超出范围时,它似乎正在发生。这是代码......

CHCF::CHCF(std::string fileName)
: PAKID("HVST84838672")
{
FILE * archive = fopen(fileName.c_str(), "rb");
std::string strGarbage = "";
unsigned int intGarbage = 0;
unsigned long longGarbage = 0;
unsigned char * data = 0;
char charGarbage = '0';

if (!archive)
{
    fclose (archive);
    return;
}

for (int i = 0; i < 12; i++)
{
    fread(&charGarbage, 1, 1, archive);
    strGarbage += charGarbage;
}


if (strGarbage != PAKID)
{
    fclose(archive);
    throw "Incorrect archive format";
}
strGarbage = "";

fread(&_gameID, sizeof(_gameID),1,archive);
fread(&_fileCount, sizeof(_fileCount),1,archive);

for (int i = 0; i < _fileCount; i++)
{
    fread(&longGarbage, 8,1,archive); //file offset

    fread(&intGarbage, 4, 1, archive);//fileName

    for (int i = 0; i < intGarbage; i++)
    {
        fread(&charGarbage, 1, 1, archive);
        strGarbage += charGarbage;
    }

    fread(&longGarbage, 8, 1, archive); //fileSize

    fread(&intGarbage, 4, 1, archive); //fileType

    data = new unsigned char[longGarbage];

    for (long i = 0; i < longGarbage; i++)
    {
        fread(&charGarbage, 1, 1, archive);
        data[i] = charGarbage;
    }

    switch ((FILETYPES)intGarbage)
    {
    case MAP:
        _maps.append(strGarbage, new CFileData(strGarbage, FILETYPES::MAP, data, longGarbage));
        break;

    default:
        break;
    }

    delete [] data;
    data = 0;
    strGarbage.clear();
    longGarbage = 0;

}
fclose(archive);
} //error happens here

这是CFileData构造函数:

CFileData::CFileData(std::string fileName, FILETYPES type, unsigned char *data, long fileSize)
{
_fileName = fileName;
_type = type;
_data = new unsigned char[fileSize];

for (int i = 0; i < fileSize; i++)
    _data[i] = data[i];
}

4 个答案:

答案 0 :(得分:2)

  1. 我可以建议std::vector而不是手动调用new和delete吗?您的代码不是异常安全的 - 如果抛出异常,则会泄漏。

  2. fread(&longGarbage, 8, 1, archive); //fileSize您确定sizeof(long)是8吗?我怀疑它是4.我相信Linux机器有时它是8,但大多数其他地方sizeof(long)是4,而sizeof(long long)是8。

  3. 这个班级成员的任何构造者怎么样?它们也可以破坏堆栈。

答案 1 :(得分:1)

正在发生的事情是写入longGarbage周围或之上的内存,这会导致损坏。

您没有说明您正在使用的开发环境。诊断此问题的一种方法是设置在特定内存位置更改时触发的断点。选择与损坏区域重叠的内存位置,并等待它意外触发。

另一种诊断方法是检查改变longGarbage周围或之上的内存的代码。当然,这几乎可以是任何事情,但可能的候选者是对“数据”的修改,对“intGarbage”的修改以及对“longGarbage”本身的修改。

我们可以进一步缩小范围,因为我们可以(通常)相当确定赋值运算符本身是安全的。像data = new...这样的代码不太可能是罪魁祸首所以我们真的需要关注涉及获取“数据”,“intGarbage”或“longGarbage”地址的内存更改。特别是内存更改会改变更多的字节数。

其他几个人已经指出长度可能不是8个字节。如果你将错误的长度传递给fread,则检索到的额外字节必须在某处。

答案 2 :(得分:0)

你正在使用大量的魔术数字来表示数据大小,所以我先检查一下。特别是,我怀疑sizeof(unsigned long)==8sizeof(unsigned in)==4在所有可能的情况下。请参阅编译器的文档,但您仍应保持警惕,因为这很可能会从一个编译器/平台更改为另一个编译器/平台。

检查这些位:

fread(&longGarbage, 8,1,archive); //file offset

您也可能希望使用C ++ <iostream>库而不是C FILE*内容进行阅读。它将允许更短的版本,因为您不需要关闭文件3次。

答案 3 :(得分:0)

从其他评论和提供的信息看来,问题出在C ++方面,你应该使用__int64用于windows环境,或者int64_t用于跨平台。