Javier Mr
Javier Mr

Reputation: 2200

Initialization of Class using malloc()

How should a c++ class be used when its memory has been reserved from a C malloc?

I'm using a C library (lua) and I need to expose a C++ class to it, in this case in order to garbage collect these reserved space, lua does the memory reservation.

A simpler similar scenario follows:

#include <string>

class Clase{
private:
    std::string valor;
public:
    Clase(){}
    Clase(const std::string & valor) : valor(valor){}
    const std::string & get() const { return this->valor; }
    void set(const std::string & valor){ this->valor = valor;}
    ~Clase(){}
};

typedef struct
{
    Clase cls;
}Estructura;

int main(int argc, char ** argv)
{
    Estructura * est = (Estructura *) malloc(sizeof(Estructura));

    est->cls.set("Hola");   // First attempt

    Clase myCls;   // Second attempt
    est->cls = myCls;

    return 0;
}

I understand, and have checked, that with malloc the class constructor is not called; that was expected, and so the copy (assign) operator can't be called with an invalid instance (the string inside Class). I suspect that the second attempt fails in the same point, when copying the string inside the Class instance.

So:

Using pointer for the Clase inside Estructura, works well, is this the best solution?

And as bonus, best way to delete the instance when lua garbage collects it?, using the __gc metamethod or is something better?

Upvotes: 7

Views: 2501

Answers (1)

Sean
Sean

Reputation: 62472

It's a bit odd to use malloc instead of new, but it is possible. You need to use placement new:

void *memory = malloc(sizeof(Estructura));

Estructura *est = new(memory)Estructura;

When you're finished with the object it's your responsibility to call the destructor yourself:

est->~Estructura();

Everything, such as vtables, will be correctly initialized, so there's no need to worry. The awkward bit is dealing with the deletion as you need to destruct the object before releasing the memory via free. delete does this automatically for you, but you'll need to do this yourself.

Upvotes: 14

Related Questions