Pepp94
Pepp94

Reputation: 11

Strange destructor call in C++

I have those inheritance classes : Base Class: Entity

Derived from Entity Classes: Actor, Obj, Enemy

The Base class Entity contains an obj of a user-defined-type that i called "CollisionStuff". When i run my program the destructor of CollisionStuff is called after every CollisionStuff constructor call and every time game-loop goes on.

so my call is: why is this happening?

As you can see below, i allocate dinamically some arrays in the setRectangle method, the programm calls the destructor, it deletes my data and when i try to use them... it calls "_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));".

Thank you in before

here my code: Entity.h

enum e_Type {tActor = 0, tObj, tEnemy, tBackg};

class Entity
{
public:
    Entity(void);
    ~Entity(void);

    float getH();
    float getW();
    void setWH(float W, float H);
    bool CreateSprite(std::string path);
    sf::Sprite& getSprite();
    void setType(e_Type type);
    e_Type getType();
    CollisionStuff getColStuff();

    static std::list<Entity*> List;

protected:
    sf::Sprite m_sprite;
    sf::Texture m_texture;
    float m_h;
    float m_w;
    e_Type m_type;
    CollisionStuff m_colStuff;

    void addToList();
};

CollisionStuff.h

class CollisionStuff
{
public:
    CollisionStuff();
    ~CollisionStuff(void);

    void setRectangle(int  W, int H);
    void followTheSprite(Entity entity);

private:
    sf::Vector2f* m_a;
    sf::Vector2f* m_b;
    sf::Vector2f* m_c;
    sf::Vector2f* m_d;
    /* this member data are sides of rectangle used
    to manage collisions between object throughout the scenario 

            a
      -------------
      |           |
    c |           | d
      |           |
      -------------
            b
    */

};

CollisionStuff.cpp

CollisionStuff::CollisionStuff()
{
    //setRectangle(0, 0);
}

void CollisionStuff::setRectangle(int W, int H)
{
    m_a = new sf::Vector2f[W];
    m_b = new sf::Vector2f[W];
    m_c = new sf::Vector2f[H];
    m_d = new sf::Vector2f[H];
}

void CollisionStuff::followTheSprite(Entity entity)
{
    entity.getSprite().setOrigin(0, 0);
    sf::Vector2f UpLeftVertex = entity.getSprite().getPosition();


    for(int i = 0; i <  entity.getW(); i++)
    {
        m_a[i].x = UpLeftVertex.x + i;
        m_a[i].y = UpLeftVertex.y;

        m_b[i].x = UpLeftVertex.x + i;
        m_b[i].y = UpLeftVertex.y + entity.getH();
    }

    for(int i = 0; i <  entity.getH(); i++)
    {
        m_c[i].x = UpLeftVertex.x;
        m_c[i].y = UpLeftVertex.y + i;

        m_d[i].x = UpLeftVertex.x + entity.getW();
        m_d[i].y = UpLeftVertex.y + i;
    }

}



CollisionStuff::~CollisionStuff(void)
{
    delete [] m_a;
    delete [] m_b;
    delete [] m_c;
    delete [] m_d;
}

EDIT Thank you for the answers. Example of CollisionStuff use

Actor.cpp (it's a derived class of Entity)

Actor::Actor(void)
{
    if(!CreateSprite("D://Sprites//MainChar.png"))
    {
        std::cout << "Impossibile creare sprite" << std::endl;
    }
    else
    {
        std::cout << "Creazione sprite riuscita" << std::endl;  
        m_sprite.setPosition(100.0f, 365.0f);
        m_sprite.setOrigin(20, 35);
        //m_sprite.setPosition(190.0f, 382.5f); // 200, 400
        setWH(40, 70);
        m_health = 100;
        m_status = Good;
        setType(tActor);
        m_jCounter = -1;
        m_action = Null;

        setColStuff();
    }
}

void Actor::setColStuff()
{
    m_colStuff.setRectangle(m_w, m_h);
}



void Actor::physic()
{
    //setColStuff();
    m_colStuff.followTheSprite(*this);
}

main.cpp

int main()
{
    sf::RenderWindow window(sf::VideoMode(800, 600), "Platform");

    std::list<Entity*>::iterator i;

    Background BG;
    Level1 FirstLev;
    Actor Doodle; 

    while(window.isOpen())
    {
        sf::Event event;
        if(window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();

            Doodle.inputEvts();
        }

        Doodle.act(Doodle.getAction());

        Doodle.physic();

        window.clear();

        window.draw(BG.getSprite());
        window.draw(Doodle.getSprite());

        FirstLev.drawLevel(window);

        window.display();
    }
    return 0;
}

Upvotes: 0

Views: 170

Answers (1)

filipe
filipe

Reputation: 3380

It's really hard to tell from the bit of code that you posted, but if I had to guess I'd say it's probably related to this:

CollisionStuff getColStuff();

you're returning CollisionStuff by value, which means a new copy will be created by whoever is calling this. It'll have the same pointers that the original CollisionStuff object allocated, and it'll delete them when it goes out of scope, leaving the original one with dangling pointers.

You can try returning by reference or by pointer, but either way you should write a copy constructor and override the assignment operator for CollisionStuff (Rule of Three).

Another idea would be to use std::vector<sf::Vector2f> instead of allocating the sf::Vector2f array yourself.

Upvotes: 2

Related Questions