Search code examples
c++pointersentityunhandled-exception

program has triggered a breakpoint, Unhandled exception at 0x77239D11 (ntdll.dll): 0xC0000374: A heap has been corrupted (parameters: 0x7726D8D0)


please skip the explanation if you know how the entity component architecture works!

Explanation:

Okay so I'm trying to create an entity component system, and i'm stuck at a very strange problem, that has never occurred until now, basically i have an Entity class which contains some variables(like name, tag, id), and a pointer vector which keeps track of all the components that get added to the entity, that's the entity class, all the components derive from the Component class, which has a type(char*), and virtual functions such as Start, Update, etc.This is how you create a component:

#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
}

My Problem:

Okay so my problem occurs only when i try to get the component of type Rigidbody2d, this is "PhysicalObject.cpp", physicalobject is a type of entity which already has some components, like a prefab, so i don't have to always add the same components to an entity type, like a physical object:

#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
}

the error points to "entity.h" getcomponent function Entity.h:

// add component, constructor, and other functions.

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

and finally the RigidBody2d.h file, which contains the rigidbody component, which is no different than other components, but still gives an error.

RigidBody2D.h: // I'm going to show all the code, because i'm not sure what might be causing the problem, so i apologize if this post becomes extremely long, also note that i've implemented the box2d library in my engine so there is some variables and functions from that, which i don't think are causing any error.

#pragma once
#include "Component.h"
#include "Transfrm.h" // i need the transform component for the rigidbody because it contains a position, rotation, etc.        

class RigidBody2D : public Component
{
public:
    b2BodyDef bodyDef;
    Transfrm* Trans;
    b2Body* Body;
    float* GScale; // this pointer needs to point to the gravity scale variable of body
    bool* FreezeRot; // this pointer needs to point to the freeze rotation variable of body
    bool IsKinematic;

    void SetGScale(float newgs){
        *GScale = newgs;
    }
    void SetFreezeRot(bool newfr) {
        *FreezeRot = newfr;
    }
    void SetIsKinetic(bool newisk) {
        IsKinematic = newisk;
    }
    RigidBody2D(float gscale = 1.f, bool fixedr = false); // constructor, before i used 2 constructors one with no parameters, but that caused me errors, because the compilier didn't know which constructor to use since they were the same(didn't require parameters)
    ~RigidBody2D();
};

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

I'm extremely sorry for the gigantic post, which took me like 2 hours to write, but I've been searching and debugging like 3 days, and still can't find a solution, because i have never encountered such problem, thanks in advance.


Solution

  • To me this part looks strange:

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

    So it looks to me that you are trying to delete something that wasn't created by new