2

I'm using a modified verison of the ECS found on thebennybox's channel (The code for which can be found here), and it works perfectly most of the time. But, when I add an std::string to a component, the program aborts on quit (when the destructor for the ECS class gets called) with the message: free(): invalid pointer. When I remove the string from the component, the program exits without problem. All the components inherit from this class:

template<typename T>
struct ECSComponent : public BaseECSComponent
{
    static const ECSComponentCreateFunction CREATE_FUNCTION;
    static const ECSComponentFreeFunction FREE_FUNCTION;
    static const uint32 ID;
    static const size_t SIZE;
};

which inherits from a class that simply contains a pointer to a vector and a couple of helper functions. The components get destroyed like so:

template<typename Component>
void ECSComponentFree(BaseECSComponent* comp)
{
    Component* component = (Component*)comp;
    component->~Component();
}

The program works with a const char* in place of the string, but I can't have that since I need this particular string to be dynamic. It also works with other common data structures such as std::vector... What is happening here?

1
  • it seems your code is trying to destroy twice something, likely is std:string included in the Component you are destroing My suggestion for debugging: write your ~Component so it output somehow "I'm destroing myself", possibly add a flag "destroyed" and set to true in dtor. Commented Aug 20, 2020 at 7:55

1 Answer 1

4

Your problem is in the ECSComponentFree() function where you call the destructor manually:

template<typename Component>
void ECSComponentFree(BaseECSComponent* comp)
{
    Component* component = (Component*)comp;
    component->~Component(); //call the destructor
}

And when your object goes out of scope, the destructor is called again which tried to free the memory again resulting in double free.

You can understand it better by running the following simple example Try Live:

class A {
    std::string* s = new std::string{"Hello"};
    public:
    A() { printf("ctor\n"); }
    void freee() { printf("freeing\n"); this->~A(); }
    ~A() { delete s; printf("dtor\n"); }
};

int main()
{
    A a;
    a.freee();
    return 0;
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.