2010-04-29 18 views
6

Estoy haciendo la transición a C++ desde C. En C++, ¿hay algún uso para la función malloc? O puedo simplemente declararlo con la palabra clave "nueva". Por ejemplo:Función Malloc en C++

class Node 
{ 
    ... 
} 
... 
Node *node1 = malloc(sizeof(Node));  //malloc 
Node *node2 = new Node;     //new 

¿Cuál debo usar?

+0

Tenga en cuenta que en C++ no hay conversión implícita de void *, entonces en el caso malloc necesita hacer 'Node * node1 = reinterpret_cast (malloc (sizeof (Node));' que claramente es demasiado tipeo. :) (De acuerdo, puedes hacer un molde C-style también, pero ¿por qué estás codificando en C++? :)) –

+5

Trata de no aplicar C a C++ demasiado, son idiomas diferentes con cosas hechas de diferentes maneras. – GManNickG

Respuesta

20

Utilice new. No debería necesitar usar malloc en un programa C++, a menos que esté interactuando con algún código C o tiene algún motivo para administrar la memoria de una manera especial.

Su ejemplo de node = malloc(sizeof(Node)) es una mala idea, porque el constructor de Node (si es que existe) no se llamaría, y una posterior delete node; tendría resultados no definidos.

Si necesita una memoria intermedia de bytes, en lugar de un objeto, por lo general, querrá hacer algo como esto:

char *buffer = new char[1024]; 

o, preferiblemente, algo como esto:

std::vector<char> buffer(1024); 

Tenga en cuenta que para el segundo ejemplo (usando std::vector<>), no es necesario delete el objeto; su memoria se liberará automáticamente cuando se salga del alcance. Debe esforzarse por evitar tanto new como malloc en los programas C++, en su lugar usar objetos que administren automáticamente su propia memoria.

+7

También puede usar 'malloc' si está asignando una memoria personalizada a través de su propio' operador :: nuevo'. – Troubadour

+1

Y recuerde que new lanza una excepción std :: bad_alloc en el fallo a menos que se llame con el modificador de nothrow! –

+1

Quizás debería agregar que nuevo es tipo seguro, mientras que el retorno de malloc es nulo *. – Joel

8

El equivalente directo de malloc() en C++ es operator new() que también asigna memoria sin procesar, sin embargo, en la mayoría de los casos, una expresión new es lo que desea. Una expresión new asigna una cantidad apropiada de memoria sin formato e inicializa un objeto en esa ubicación de memoria, devolviendo un puntero tipeado correctamente al nuevo objeto.

En su caso, new Node es correcto, ya que asigna memoria e inicializa un nuevo objeto Node. Simplemente llamando al malloc y el resultado de la conversión a un puntero a Node no construirá correctamente el objeto Node. Esto es crítico si Node no es una estructura POD (por ejemplo, cuando uno de sus subobjetos o un subproducto tiene un constructor al que se debe llamar).

Debe evitar la asignación dinámica cuando no sea necesaria; donde sea necesario, a menudo es mejor inicializar algún tipo de puntero inteligente con la dirección del objeto dinámicamente asignado para que no sea posible 'olvidar' delete el obejct.

2

Bueno, la única cosa que se me ocurre, si estás utilizando algo nuevo vas a extrañar realloc si terminas necesitándolo.

+3

'realloc' no funciona con tipos que no sean POD, por lo que casi siempre se prefiere usar un' vector' en C++. –

1

La situación clave en la que debe usar malloc es si el código original alguna vez llama al realloc. Por supuesto, puede volver a implementar todo lo necesario, pero no hay tanta ventaja al hacerlo.

+0

'realloc()' es con frecuencia una mala noticia en C++, ya que los objetos de datos que no son POD suelen ser alérgicos a que se muevan arbitrariamente. Use un 'vector <>' en su lugar. No solo hace la gestión de la memoria por ti, sino que lo hace correctamente. –

+0

En el código C que veo, realloc casi siempre se utiliza en matrices de bytes o matrices de punteros. Ambos son POD. – Joshua

1

Mi costumbre es utilizar malloc() para tipos primitivos y estructuras compatibles con C, y nuevo para todo lo demás.

3

Una de las principales diferencias entre new y malloc es que new llamará al constructor del objeto.

Otra diferencia es que new arrojará una excepción (puede ser evadida por un compilador pragma) si la memoria no se puede asignar con éxito. El malloc puede causar que se genere una señal del sistema. Aunque algunas bibliotecas C++ implementan new llamando al malloc.

Puede haber algunos casos en los que los objetos se deben asignar dinámicamente sin invocar a sus constructores. En más de 20 años, no he encontrado ninguno (ni siquiera en el ámbito de los sistemas integrados).

1

En general, use new, excepto cuando haga interfaz con el código C.

El punto clave de esto es que lo que está asignado con new debe ser liberado con delete, y lo que se asigna con malloc deben ser liberados con free. No puede asignar con new y gratis con free() o viceversa. Entonces, la única vez que necesita malloc es cuando necesita pasar datos a algún código C que podría free() o realloc().