围绕变量的堆栈损坏,不确定是什么问题

问题描述

| 问题解决了,谢谢大家的帮助 我在这里遇到了一些问题,这不是让我的程序崩溃的原因,但是我无法解决它只是困扰我。我有一个函数文件中读取一些数据,在执行结束时,变量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,archive);
    strGarbage += charGarbage;
}


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

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

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

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

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

    fread(&longGarbage,archive); //fileSize

    fread(&intGarbage,archive); //fileType

    data = new unsigned char[longGarbage];

    for (long i = 0; i < longGarbage; i++)
    {
        fread(&charGarbage,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];
}
    

解决方法

        发生的情况是,有一些东西正在写入到longGarbage周围或上方的内存中,这导致了损坏。 您没有说您正在使用什么开发环境。诊断此问题的一种方法是设置一个断点,该断点在特定的内存位置更改时触发。选择与损坏区域重叠的内存位置,然后等待它意外触发。 诊断此问题的另一种方法是检查在longGarbage周围或上方更改内存的代码。当然,这几乎可以是任何东西,但可能的候选者是对“数据”的修改,对“ intGarbage”的修改以及对“ longGarbage”本身的修改。 我们可以进一步缩小范围,因为(通常)我们可以相当确定赋值运算符本身是安全的。像
data = new...
这样的代码不太可能是罪魁祸首,因此实际上我们需要专注于涉及采用\'data \',\'intGarbage \'或\'longGarbage \'地址的内存更改。特别是内存更改,更改后的字节数超出其应有的数量。 其他一些人已经指出,长可能不是8个字节。如果传递错误的长度以进行读取,则检索到的多余字节必须放在某个地方。     ,         我可能建议使用
std::vector
,而不要手动调用new和delete?您的代码不是异常安全的-如果引发异常,则会泄漏。
fread(&longGarbage,8,1,archive); //fileSize
确定
sizeof(long)
是8吗?我怀疑它是4。我相信在Linux机器上有时是8,但其他大多数地方ѭ5是4,and7是8。 此类成员的任何构造函数如何?他们也可能破坏堆栈。     ,        您正在使用许多幻数来表示数据大小,因此我将首先对其进行检查。我特别怀疑在所有可能的情况下ѭ8和ѭ9。请参阅编译器的文档,但您仍应保持警惕,因为这很可能从一种编译器/平台更改为另一种。 检查以下位:
fread(&longGarbage,archive); //file offset
您可能还想使用C ++
<iostream>
库而不是C
FILE*
库进行阅读。它将允许使用更短的版本,因为您不需要关闭文件3次。     ,        从其他注释和提供的信息看来,问题出在C ++方面,对于Windows环境,应使用__int64,对于跨平台应使用int64_t。     

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...