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

C++ 程序已在0x77239D11(ntdll.dll)处触发断点、未处理的异常:0xC0000374:堆已损坏(参数:0x7726D8D0),c++,pointers,entity,unhandled-exception,C++,Pointers,Entity,Unhandled Exception,如果您知道实体组件体系结构是如何工作的,请跳过说明 说明: 好的,我正在尝试创建一个实体组件系统,我被一个非常奇怪的问题困住了,这个问题到现在为止从未发生过,基本上我有一个实体类,它包含一些变量(比如名称、标记、id),还有一个指针向量,它跟踪添加到实体中的所有组件,这就是实体类,所有组件都派生自Component类,该类具有类型(char*)和虚拟函数,如Start、Update等。这就是创建组件的方式: #pragma once class printcomponent : public C

如果您知道实体组件体系结构是如何工作的,请跳过说明

说明:

好的,我正在尝试创建一个实体组件系统,我被一个非常奇怪的问题困住了,这个问题到现在为止从未发生过,基本上我有一个实体类,它包含一些变量(比如名称、标记、id),还有一个指针向量,它跟踪添加到实体中的所有组件,这就是实体类,所有组件都派生自Component类,该类具有类型(char*)和虚拟函数,如Start、Update等。这就是创建组件的方式:

#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.cpp:

#include "stdafx.h"
#include "Public.h"
#include "RigidBody2D.h"

RigidBody2D::RigidBody2D(float gscale, bool fixedr) : Component("RigidBody2D")
{
    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;
    bodyDef.fixedRotation = fixedr;
    GScale = &bodyDef.gravityScale;
    FreezeRot = &bodyDef.fixedRotation;
    Body = CurrentPhysicsWorld->CreateBody(&bodyDef);
}
RigidBody2D::~RigidBody2D() {
    delete Trans;
    delete GScale;
    delete FreezeRot;
    CurrentPhysicsWorld->DestroyBody(Body);
};

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

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

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);
};

因此,在我看来,您正试图
删除
一些不是由
新建的

创建的内容。在我看来,这部分内容看起来很奇怪:

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);
};

因此,在我看来,您正试图
删除
一些不是由
新建的
创建的东西,这些东西非常突出:

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

~rigidibody2d()
中,您正在
删除
两个对象-
GScale
FreezeRot
,它们不是使用
new
创建的,而是属于
bodyDef

当然,这是未定义的

很难猜测这两项是否足以解决您的问题。

根据您发布的代码,我怀疑可能还有许多其他类似的问题需要解决。

有几件事很突出:

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

~rigidibody2d()
中,您正在
删除
两个对象-
GScale
FreezeRot
,它们不是使用
new
创建的,而是属于
bodyDef

当然,这是未定义的

很难猜测这两项是否足以解决您的问题。

根据您发布的代码,我怀疑可能还有许多其他类似的问题需要解决。

我认为问题在于您如何手动删除
GScale
FreezeRot
。在
GetComponent
中,您创建了一个临时对象T,它将在函数结束时超出范围。如果搜索刚体类型,函数完成时将调用它的析构函数,删除一些应该留给Box2D管理的指针

作为修复,我建议删除删除这两个成员的代码,并为每种类型创建一个名为type的静态成员,以便您可以执行以下操作:

T::Type

不必创建临时对象:

T t;
T.type

我认为问题在于如何手动删除
GScale
FreezeRot
。在
GetComponent
中,您创建了一个临时对象T,它将在函数结束时超出范围。如果搜索刚体类型,函数完成时将调用它的析构函数,删除一些应该留给Box2D管理的指针

作为修复,我建议删除删除这两个成员的代码,并为每种类型创建一个名为type的静态成员,以便您可以执行以下操作:

T::Type

不必创建临时对象:

T t;
T.type

我强烈建议您一起学习使用“gdb”和“valgrind”。在处理内存错误(如堆损坏)时,这些工具可以显著减少调试时间。我强烈建议您学习同时使用“gdb”和“valgrind”。在处理内存错误(如堆损坏)时,这些工具可以显著缩短调试时间。很抱歉,这是一个错误,请原谅所有的错误,因为在我的实际程序中没有错误。是的,在删除这两行之后,它被修复了,谢谢洛蒂。很抱歉,这是一个错误,请原谅所有的错误,因为在我的实际程序中没有。是的,它是固定的,在删除了那两行之后,谢谢你,我知道我想这样做,但它会带来更多的问题,因为你不能从构造函数中设置静态成员,对吗?这就是它的工作方式(高速),但在我编辑physicalobject类和rigidbody2d componetnNo之后,它就不再工作了。不,你可以在任何成员函数之外设置它们。我知道我想这样做,但它会带来更多问题,因为你不能从构造函数中设置静态成员,对吗?这是它的工作方式(高速),但在我编辑physicalobject类和rigidbody2d组件之后,它就不再工作了。不,您可以在任何成员函数之外设置它们。
T t;
T.type