Para una class
o struct
como su example
, la respuesta correcta es utilizar new
no malloc()
asignar una instancia. Solo operator new
sabe cómo llamar a los constructores para el struct
y sus miembros. Su problema es causado por el miembro de cadena que no se haya construido nunca.
Sin embargo, hay casos raros donde es importante que un parche de memoria en particular actúe como si tuviera una instancia de una clase. Si realmente tiene un caso así, existe una variación de operator new
que permite especificar la ubicación del objeto. Esto se llama "placement new" y debe usarse con sumo cuidado.
void *rawex = malloc(sizeof(example)); // allocate space
example ex = new(rawex) example(); // construct an example in it
ex->data = "hello world"; // use the data field, not no crash
// time passes
ex->~example(); // call the destructor
free(rawex); // free the allocation
Al utilizar la ubicación nueva, está obligado a proporcionar un área de memoria del tamaño y la alineación correctos. No proporcionar el tamaño o la alineación correctos hará que las cosas misteriosas salgan mal. La alineación incorrecta suele ser más rápida para causar un problema, pero también puede ser misteriosa.
Además, con una ubicación nueva, se está responsabilizando de llamar al destructor a mano, y dependiendo del origen del bloque de memoria, liberándolo a su propietario.
Con todo, a menos que ya sepa que necesita una ubicación nueva, es casi seguro que no la necesita. Tiene usos legítimos, pero hay rincones oscuros de marcos y no ocurrencias cotidianas.
Estoy usando malloc() porque new arroja excepciones en lugar de devuelve NULL. Simplemente no quería excepciones en esa parte del código. Ese código ocurre en una devolución de llamada de C y no quiero lanzar excepciones de C++ en una devolución de llamada de C. Entonces usé malloc. ¿Alguna idea sobre eso? – bodacydo
@bodacydo: puede usar 'new (std :: nothrow) example' para hacer que' new' devuelva null-pointer en lugar de lanzar excepciones. Debe incluir el encabezado '' para usar la constante 'std :: nothrow'. –
AnT
@bodacydo: si realmente quiere 'new' devolver un puntero nulo en caso de error, use' new (nothrow) example'. Pero realmente deberías usar 'try' /' catch' para atrapar cualquier excepción lanzada. (La asignación 'std :: string', por ejemplo, también podría arrojar una excepción si no puede asignar memoria.) – jamesdlin