程序触发了断点,0x77239D11处于未处理的异常(ntdll.dll):0xC0000374:堆已损坏(参数:0x7726D8D0)

时间:2017-01-02 17:37:00

标签: c++ pointers entity unhandled-exception

如果您知道实体组件架构的工作原理,请跳过说明!

解释

好的,所以我试图创建一个实体组件系统,并且我遇到了一个非常奇怪的问题,直到现在才发生过,基本上我有一个包含一些变量的Entity类(比如name,tag,id)和一个指针向量,它跟踪所有添加到实体的组件,即实体类,所有组件都派生自Component类,它具有一个类型(char * ),以及虚拟功能,如开始,更新等。这是您创建组件的方式:

a[0]

我的问题:

好吧所以我的问题只有在我尝试获取Rigidbody2d类型的组件时才会发生,这是" PhysicalObject.cpp",physicalobject是一种已经有一些组件的实体,比如预制件,所以我不必总是将相同的组件添加到实体类型,如物理对象:

>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a[:-1]
[0, 1, 2, 3, 4, 5, 6, 7, 8]
>>> a[-2::-1]
[8, 7, 6, 5, 4, 3, 2, 1, 0]

错误指向" entity.h" getcomponent函数 Entity.h:

//添加组件,构造函数和其他函数。

#pragma once
class printcomponent : public Component {
  printcomponent() : Component("printcomponent"){} // the printcomponent constructor derives from the component constructor which takes a char* as parameter, and sets the component's type to that char*
 void Start(){
 cout << "This is printed on start" << endl;
} 
void Update(){
 cout << "This gets printed every frame" << endl;
}
 ~printcomponent();//destructor
}

最后是RigidBody2d.h文件,它包含刚体组件,与其他组件没有什么不同,但仍然会出错。

RigidBody2D.h://我将显示所有代码,因为我不确定导致问题的原因,所以如果这个帖子变得非常长,我会道歉,同时请注意我和#39;在我的引擎中实现了box2d库,因此有一些变量和函数,我认为这不会导致任何错误。

#include "stdafx.h"
#include "Public.h" // all the public variables are in here, and declared in Public.cpp
#include "PhysicalObject.h"

PhysicalObject::PhysicalObject(float boxwidth, float boxheight, float gscale, bool fixedr, float nDnsity, float nFricton, string name, string tag, bool isactive, bool isstatic) : Entity(name, tag, isactive, isstatic) // so basically the constructor creates an entity
{
    this->AddComponent<Transfrm>(b2Vec2(0.f, 0.f), 0.f, b2Vec2(1.f, 1.f)); // i add a transform component
    this->AddComponent<RigidBody2D>(gscale, fixedr); // i add a rigidbody2d component, there is no problem when adding components
    this->AddComponent<SprtRend>(this); // again spriterenderer component
    trans = this->GetComponent<Transfrm>(); // okay so i have 2 variables for easily accessing specific components, i have one trans for transform, and one rigidb for rigidbody2d, basically calling this instead of getting component is much more efficient !
    rigidb = this->GetComponent<RigidBody2D>(); // this is the line causing me problems, the previous line doesn't cause any problem, but this causes an  Unhandled exception, in the function GetComponent of Entity.h
}

最后是RigidBody2D.cpp:

template <typename T>
T* GetComponent() {
    T t; // so basically this function creates a new given type T and loops through all the components until it finds a matching type
    for (unsigned i = 0; i < AllComponents.size(); i++) {
        if (AllComponents.at(i)->Type == t.Type) { // when debugging in this line, in the 'autos' window, it shows the type as "RigidBody2D", which is fine, but after i continue to the other line, it gives me the unhandled exception and the type of 't' is something like: "/x" and some numbers, which makes no sense, and doesn't occur when getting other components.
            return dynamic_cast<T*>(AllComponents.at(i));
            break;
        }
    }
    cout << "Entity: " << Name << " Does Not Have Component of Type: " << t.Type << endl;
}

// desctructor

我非常抱歉这篇巨大的帖子让我花了2个小时写作,但我已经进行了3天的搜索和调试,仍然无法找到解决方案,因为我从未遇到过这样的问题,提前谢谢。

3 个答案:

答案 0 :(得分:1)

对我来说这部分看起来很奇怪:

RigidBody2D::RigidBody2D(float gscale, bool fixedr) : Component("RigidBody2D")
                               ^^^^^^^ gscale is a float
{
    Trans = new Transfrm(b2Vec2(0.f, 0.f), 0.f, b2Vec2(1.f, 1.f));
    bodyDef.type = b2_dynamicBody;
    bodyDef.position.Set(Trans->Position.x, Trans->Position.y);
    bodyDef.gravityScale = gscale;
                           ^^^^
                           Used for initialization of bodyDef.gravityScale 

    bodyDef.fixedRotation = fixedr;
    GScale = &bodyDef.gravityScale;
    ^^^^^^
    Pointer to bodyDef.gravityScale

    FreezeRot = &bodyDef.fixedRotation;
    Body = CurrentPhysicsWorld->CreateBody(&bodyDef);
}
RigidBody2D::~RigidBody2D() {
    delete Trans;
    delete GScale;
    ^^^^^^^^
    Delete of bodyDef member which wasn't created by new        



    delete FreezeRot;
    CurrentPhysicsWorld->DestroyBody(Body);
};

因此,我认为您正在尝试delete某些非new

创建的内容

答案 1 :(得分:1)

有一些突出的事情:

GetComponent并不总是返回任何内容,这很容易导致未定义的行为。

~RigidBody2D()中,您{{}} {{}}两个对象 - deleteGScale - 这些对象不是使用FreezeRot创建的,而是拥有的按new
当然,这是未定义的。

这两个是否足以解决你的问题很难猜到 根据您发布的代码,我怀疑还有很多其他类似问题可以追捕。

答案 2 :(得分:0)

我认为问题在于您手动删除GScaleFreezeRot的方式。在GetComponent中,您创建了一个临时对象T,它将在函数末尾超出范围。如果你搜索一个RigidBody类型,它将在函数完成时调用析构函数,删除一些应留给Box2D来管理的指针。

作为修复,我建议删除代码帽删除这两个成员,并为每种类型创建一个名为Type的静态成员,以便您可以这样做:

T::Type

而不是必须创建一个临时对象:

T t;
T.type