Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 解构器中的堆损坏_C++ - Fatal编程技术网

C++ 解构器中的堆损坏

C++ 解构器中的堆损坏,c++,C++,我正在创建一个反编译一些游戏脚本文件的程序。我添加的最新部分在处理动态数组时给了我一些错误。这就是违规代码: typedef struct _COD9_ANIMREF_1 { DWORD name; DWORD reference; }; typedef struct _COD9_USEANIM_1 { WORD name; // offset of name WORD numOfReferences; // reference count WORD n

我正在创建一个反编译一些游戏脚本文件的程序。我添加的最新部分在处理动态数组时给了我一些错误。这就是违规代码:

typedef struct _COD9_ANIMREF_1
{
    DWORD name;
    DWORD reference;
};

typedef struct _COD9_USEANIM_1
{
    WORD name; // offset of name
    WORD numOfReferences; // reference count
    WORD numOfAnimReferences; // reference count
    WORD null1; // always null
    DWORD* references = NULL; // dynamic array of references, amount = numOfReferences
    _COD9_ANIMREF_1* animReferences = NULL; // dynamic array of references, amount = numOfAnimReferences
    ~_COD9_USEANIM_1()
    {
        if (references)
            delete[] references;
        if (animReferences) // program officially breaks here, if continued causes heap corruption
            delete[] animReferences;
    }
};
typedef struct _COD9_WORK_1
{
    _COD9_GSC_1 Hdr;
    char* data = NULL;
    int* includes = NULL;               //done
    _COD9_USEANIM_1* usingAnim = NULL;  //not done, heap corruption
    _COD9_STRING_1* strings = NULL; //done
    _COD9_FUNC_1* functions = NULL; //done
    _COD9_EXTFUNC_1* extFunctions = NULL; //done
    _COD9_RELOC_1* relocations = NULL;  //done
    ~_COD9_WORK_1()
    {
        if (data)
            delete[] data;
        if (includes)
            delete[] includes;
        if (usingAnim)
            delete[] usingAnim;
        if (strings)
            delete[] strings;
        if (functions)
            delete[] functions;
        if (extFunctions)
            delete[] extFunctions;
        if (relocations)
            delete[] relocations;
    }
};
if (tstg.Hdr.numOfUsinganimtree)
{
    tstg.usingAnim = new _COD9_USEANIM_1[tstg.Hdr.numOfUsinganimtree];
    igsc.seekg(tstg.Hdr.usinganimtreeStructs);
    for (int i = 0; i < tstg.Hdr.numOfUsinganimtree; i++)
    {
        _COD9_USEANIM_1 anim;
        igsc.read(reinterpret_cast<char*>(&anim.name), sizeof(anim.name));
        igsc.read(reinterpret_cast<char*>(&anim.numOfReferences), sizeof(anim.numOfReferences)); // this is 0 in this instance
        igsc.read(reinterpret_cast<char*>(&anim.numOfAnimReferences), sizeof(anim.numOfAnimReferences));
        igsc.read(reinterpret_cast<char*>(&anim.null1), sizeof(anim.null1));
        anim.references = new DWORD[anim.numOfReferences]; // allocate 0 size array so theres something to delete
        if(anim.numOfReferences) // should not be entered
        {
            igsc.read(reinterpret_cast<char*>(&anim.references), (anim.numOfReferences*sizeof(DWORD))); // if numOfReference = 0, function should return
        }
        anim.animReferences = new _COD9_ANIMREF_1[anim.numOfAnimReferences];
        for (int ii = 0; ii < anim.numOfAnimReferences; ii++)
        {
            _COD9_ANIMREF_1 animref;
            igsc.read(reinterpret_cast<char*>(&animref.name), sizeof(animref.name));
            igsc.read(reinterpret_cast<char*>(&animref.reference), sizeof(animref.reference));
            anim.animReferences[i] = animref;
        }
        tstg.usingAnim[i] = anim;
        printf("anim: %d\n", i); // program reaches this
    }
    printf("Anims Done\n"); // program doesn't reach this
    ReorderUsingAnim(&tstg);
}

我认为错误发生在引用数组中,因为从技术上讲,这个实例中的大小是0。但我不知道该怎么办,而且我也对堆损坏的一般情况感到迷茫。

\u COD9\u USEANIM\u 1
(为什么哦,为什么新手会使用如此可怕的名称?他们调用变量,比如“Z\u ASHD532\uuuuuu8ahq”?)有两个数组(为什么不使用向量??),
参考
动画参考
。它有一个析构函数,如果指针不为零,它将释放数组但没有构造函数。这很危险。至少,您应该提供一个构造函数,将
引用
动画引用
初始化为零。您还需要复制构造函数。记住这条规则:如果您提供三个构造函数中的一个(默认构造函数、析构函数、复制构造函数),那么您几乎肯定需要这三个

好,现在开始循环

for (int i = 0; i < tstg.Hdr.numOfUsinganimtree; i++)
您分配其
引用
引用

anim.references = new DWORD[anim.numOfReferences];
...
anim.animReferences = new _COD9_ANIMREF_1[anim.numOfAnimReferences];
最后将其复制到
tstg.usingAnim

_COD9_USEANIM_1 anim;
tstg.usingAnim[i] = anim;
你知道当你复制它时会发生什么吗?所有字段都只是复制。所以现在
tstg的
references
animferences
。使用anim[i]
指向与anim的
references和
animferences
相同的地址

然后,块结束。邪恶的计算机为
anim
调用析构函数。析构函数为
anim.references
anim.animferences
调用delete[]。但是,
tstg的
references
animpreferences
。usingAnim[i]
指向相同的地址。换句话说,它们现在指向已删除的数组

现在,堆的行为是不可预测的

最好的建议是:忘记数组,使用向量。你知道,
std::vector
来自标准库

第二个最佳建议:提供默认构造函数和复制构造函数。(PS:和分配操作员!)


(请注意,您的程序可能还存在其他错误。)

停止使用数组,并使用
std::vector
。如果(membervar)delete[]membervar
语句,则会出现大量
。这些都假设变量如果没有分配,则默认为null,但我没有看到任何初始化它们的构造函数。由于这是C++,所以不需要<代码> TyBuffsStult。这是从代码> C <代码>中的一个保留,而C++中不需要。您所需要的就是
struct
我对堆损坏的一般情况非常了解
——停止使用导致堆损坏的构造。使用
std::vector
而不是
new[]/delete[]
,这将消除大部分(如果不是所有的话)堆损坏问题。谷歌“三个法则”。我甚至没有这样想。不过我不想讨论向量,所以我会尽快研究复制构造函数。如果不行,我想我别无选择。感谢您的澄清。3的规则不适用于默认构造函数、复制构造函数和析构函数。它用于复制构造函数、析构函数和赋值运算符。好的,它是真的。但是在这种情况下,也应该实现默认构造函数。对于原始海报:您还应该实现赋值运算符。詹姆斯·阿德基森是对的。
tstg.usingAnim[i] = anim;