2015-05-05 2 views
3

Как должен использоваться класс C++, когда его память зарезервирована из C malloc?Инициализация класса с помощью malloc()

Я использую библиотеку C (lua), и мне нужно открыть для него класс C++, в этом случае, чтобы мусор собирал эти зарезервированные пространства, lua делает резервирование памяти.

Более простой подобный сценарий следующим образом:

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

Я понимаю, и проверил, что с таНосом конструктор класса не вызывается; что ожидалось, и поэтому оператор copy (assign) не может быть вызван с недопустимым экземпляром (строка внутри класса). Я подозреваю, что вторая попытка не удалась в той же точке при копировании строки внутри экземпляра класса.

Итак:

  • возможно правильно инициализировать экземпляр класса, который его память зарезервирована таНос?
  • Какие еще оговорки есть ?, vtables?
  • будет свободным дополнением к malloc оставить утечки памяти? (Я предполагаю, что поскольку деструктор Clase не будет называться, строка не будет правильно освобождена? [Я предполагаю, что строка хранит память вне самого экземпляра])

Использование указателя для класа внутри Estructura, хорошо работает, это лучшее решение?

И как бонус, лучший способ удалить экземпляр, когда мусор lua его собирает ?, используя мета-метод __gc или что-то лучше?

+2

http://stackoverflow.com/a/222578/3385212 – tynn

+0

Лучшее решение может заключаться в том, чтобы написать оболочку среднего уровня для интерфейса C на C++. Начните определять функцию C++, вне класса, которые используют new для инициализации класса и возврата указателя на созданный объект. Создать оболочку для общедоступных методов. – LPs

+0

Почему у вас есть обертка «Estructura»? (И нет никакого указателя в вашем коде, кстати.) –

ответ

9

Немного странно использовать malloc вместо new, но это возможно. Вы должны использовать размещение новых:

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

Estructura *est = new(memory)Estructura; 

Когда вы закончите с объектом, это ваша ответственность, чтобы вызывать деструктор себя:

est->~Estructura(); 

Все, например, виртуальных таблиц, будет правильно инициализирован, так нет необходимости беспокоиться. Неловкий бит имеет дело с удалением, поскольку вам нужно уничтожить объект, прежде чем освобождать память через free. delete делает это автоматически для вас, но вам нужно сделать это самостоятельно.

+0

Протестировано и отлично работает. Не знал о размещении нового. Благодарю. –

Смежные вопросы