2010-04-29 12 views
6

Sto passando a C++ da C. In C++, c'è qualche utilizzo per la funzione malloc? O posso solo dichiararlo con la parola chiave "nuova". Ad esempio:Funzione Malloc in C++

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

Quale dovrei usare?

+0

Si noti che in C++ non esiste cast implicito da void *, quindi sul caso malloc è necessario eseguire effettivamente 'Node * node1 = reinterpret_cast (malloc (sizeof (Node)) ;, che è chiaramente troppo digitato. :) (Ok ok, puoi anche fare un cast in stile C, ma allora perché stai codificando in C++? :)) –

+5

Cerca di non applicare troppo C a C++, sono lingue diverse con cose fatte in modi diversi. – GManNickG

risposta

20

Utilizzare new. Non dovresti aver bisogno di usare malloc in un programma C++, a meno che non stia interagendo con qualche codice C o hai qualche motivo per gestire la memoria in un modo speciale.

Il tuo esempio di node = malloc(sizeof(Node)) è una cattiva idea, perché il costruttore di Node (se ne esistono) non sarebbe stato chiamato, e una successiva delete node; avrebbe risultati non definiti.

Se avete bisogno di un buffer di byte, piuttosto che un oggetto, avrete generalmente vuole fare qualcosa di simile:

char *buffer = new char[1024]; 

o, preferibilmente, qualcosa di simile:

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

Si noti che per il secondo esempio (utilizzando std::vector<>), non è necessario delete l'oggetto; la sua memoria verrà automaticamente liberata quando esce dal campo di applicazione. Dovresti sforzarti di evitare entrambi i programmi new e malloc in programmi C++, invece di utilizzare oggetti che gestiscono automaticamente la propria memoria.

+7

Si potrebbe anche usare 'malloc' se si sta eseguendo l'allocazione della memoria personalizzata tramite il proprio' operator :: new'. – Troubadour

+1

E ricorda che new genera un'eccezione std :: bad_alloc in caso di errore a meno che non chiami con il modificatore nothrow! –

+1

Dovrebbe forse aggiungere che nuovo è sicuro, mentre il ritorno da malloc è nullo *. – Joel

8

L'equivalente diretto di malloc() in C++ è operator new() che alloca anche la memoria non elaborata, tuttavia nella maggior parte dei casi l'espressione new è ciò che si desidera. Un'espressione new alloca una quantità appropriata di memoria non elaborata e inizializza un oggetto in tale posizione di memoria, restituendo un puntatore correttamente digitato al nuovo oggetto.

Nel tuo caso, new Node è corretto in quanto assegna memoria e inizializza un nuovo oggetto Node. È sufficiente chiamare malloc e il risultato della trasmissione su un puntatore su Node non costruirà correttamente l'oggetto Node. Questo è fondamentale se Node non è una struttura POD (ad esempio quando o uno dei suoi oggetti secondari ha un costruttore che deve essere chiamato).

È necessario evitare l'allocazione dinamica laddove non è necessaria; dove è necessario, è spesso meglio inizializzare una sorta di puntatore intelligente con l'indirizzo dell'oggetto dinamicamente assegnato in modo che non sia possibile 'dimenticare' a delete l'obejct.

2

Bene, l'unica cosa a cui riesco a pensare, se si sta usando un nuovo, mancheranno realloc se si finisce per averne bisogno.

+3

'realloc' non funziona con i tipi non POD, quindi l'uso di un' vector' è quasi sempre preferito in C++. –

1

La situazione chiave in cui è necessario utilizzare malloc è se il codice originale chiama sempre realloc. Ovviamente è possibile reimplementare tutto ciò che è necessario, ma non c'è molto vantaggio nel farlo.

+0

'realloc()' è spesso una cattiva notizia in C++, poiché gli oggetti di dati non POD sono solitamente allergici all'essere spostati in modo arbitrario. Usa invece un 'vector <>'. Non solo la gestione della memoria per te, lo fa correttamente. –

+0

Nel codice C che vedo, realloc viene quasi sempre utilizzato su matrici di byte o matrici di puntatori. Entrambi sono POD. – Joshua

1

La mia abitudine è usare malloc() per i tipi primitivi e le strutture C compatibili, e nuovo per tutto il resto.

3

Una delle differenze principali tra new e malloc è che new chiamerà il costruttore dell'oggetto.

Un'altra differenza è che new genererà un'eccezione (potrebbe essere aggirata da un compilatore pragma) se la memoria non può essere allocata correttamente. malloc può causare la generazione di un segnale di sistema. Sebbene alcune librerie C++ implementino new chiamando malloc.

Ci possono essere alcuni casi in cui gli oggetti devono essere allocati dinamicamente senza invocare i loro costruttori. In oltre 20 anni, non ne ho mai visto nessuno (nemmeno nell'arena dei sistemi embedded).

1

In generale, utilizzare new tranne quando si interfaccia con il codice C.

Il punto chiave di questo è che ciò che è allocato con new da liberare con delete, e ciò che è allocato con malloc deve essere liberata con free. Non è possibile assegnare con new e gratuito con free() o viceversa. Quindi, circa l'unica volta che è necessario malloc è quando è necessario trasferire i dati su un codice C che potrebbe essere free() o realloc().