¿Cómo usar una cadena C ++ en una estructura cuando malloc () – ing la misma estructura?

Escribí el siguiente progtwig de ejemplo, pero se bloquea con segfault. El problema parece ser con el uso de malloc y std::string s en la estructura.

 #include  #include  #include  struct example { std::string data; }; int main() { example *ex = (example *)malloc(sizeof(*ex)); ex->data = "hello world"; std::cout <data << std::endl; } 

No puedo entender cómo hacerlo funcionar. ¿Alguna idea si es posible utilizar malloc() y std::string s?

Gracias, Boda Cydo.

No puede malloc una clase con un constructor no trivial en C ++. Lo que obtienes de malloc es un bloque de memoria en bruto , que no contiene un objeto correctamente construido. Cualquier bash de usar esa memoria como un objeto “real” fallará.

En lugar de malloc -ing object, use new

 example *ex = new example; 

También se puede forzar el código original para que funcione con malloc , utilizando la siguiente secuencia de pasos: malloc raw memory primero, construya el objeto en ese segundo en bruto de memoria:

 void *ex_raw = malloc(sizeof(example)); example *ex = new(ex_raw) example; 

La forma de new usado arriba se llama “colocación nueva”. Sin embargo, no hay necesidad de todos estos trucos en su caso.

Asignar memoria con malloc no llama a ningún constructor. No mezcle la asignación estilo C con objetos C ++ . No juegan bien juntos. En su lugar, use el new operador para asignar objetos en el código C ++:

 example *ex = new example; 

Este es un código más inteligente y llamará al constructor std::string::string() para inicializar la cadena, lo que arreglará el segfault que estás viendo. Y no olvides eliminarlo cuando hayas terminado de liberar la memoria y llamar a los destructores correspondientes:

 delete ex; 

Para una class o struct como su example , la respuesta correcta es usar new not malloc() para asignar una instancia. Solo el operator new sabe cómo llamar a los constructores para la struct y sus miembros. Su problema es causado por el miembro de cadena que no se haya construido nunca.

Sin embargo, hay casos excepcionales en los que 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í, entonces hay una variación del operator new que permite especificar la ubicación del objeto. Esto se llama “colocación nueva” y se debe usar con gran 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 una región 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 responsabiliza de llamar al destructor a mano y, dependiendo del origen del bloque de memoria, liberarlo a su propietario.

En general, 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.

El problema es que malloc no llama al constructor del example . Dado que una string generalmente se representa como un puntero en la stack, se establece en cero y se desreferencia un puntero nulo. Necesita usar new lugar.

no deberías usar

ejemplo * ex = (ejemplo *) malloc (sizeof (* ex));

porque qué sizeof (* ex) return es igual al tamaño de long o size de int, lo cual se debe a que el entorno de comstackción es diferente. puedes usar el código de la siguiente manera:

ejemplo * ex = (ejemplo *) malloc (sizeof (ejemplo));