2010-05-15 13 views

risposta

32

Non c'è new/delete espressione in C.

L'equivalente più vicino è il malloc and free functions, se si ignorano i costruttori/distruttori e la sicurezza di tipo.

#include <stdlib.h> 

int* p = malloc(sizeof(*p)); // int* p = new int; 
... 
free(p);      // delete p; 

int* a = malloc(12*sizeof(*a)); // int* a = new int[12]; 
... 
free(a);       // delete[] a; 
+2

* @ KennyTM: * Fa 'sizeof (* p)' in realtà dereferenziazione 'p', o è completamente equivalente alla scrittura' sizeof (int) '? Sembra che nel primo caso, questa espressione possa potenzialmente causare un errore di segmentazione (poiché "p" non è ancora stato assegnato a questo punto). In quest'ultimo caso, probabilmente preferirei ancora scrivere 'sizeof (int)' perché c'è meno potenziale di incomprensione su ciò che questa affermazione fa. – stakx

+5

@stakx: l'operatore 'sizeof' viene valutato al momento della compilazione. Non c'è il dereferenziamento. 'sizeof (* p)' è preferito a 'sizeof (int)' perché se si modifica il tipo di 'p' in' double' il compilatore non può avvisare della mancata corrispondenza delle dimensioni. – kennytm

+8

@stakx L'operatore 'sizeof' è un mapping da ** tipo ** a' size_t'. Il ** valore ** del suo operando non è affatto interessante. Ad esempio, in 'sizeof (1 + 2)', non c'è assolutamente bisogno di calcolare il risultato '3'. L'operatore 'sizeof' vede semplicemente un'espressione di tipo' int + int' e deduce che il risultato è anche un 'int'. Quindi mappa 'int' su 4 (o 2 o 8, a seconda della piattaforma). È la stessa cosa con 'sizeof (* p)'. Il sistema di tipi sa che, a livello di tipo, il dereferenziamento di un 'int *' produce un 'int'. 'sizeof' non è interessato al valore di' * p', solo il tipo conta. – fredoverflow

3

Non direttamente una replica esatta ma equivalenti compatibili sono malloc e gratuiti.

<data-type>* variable = (<data-type> *) malloc(memory-size); 
free(variable); 

Nessun costruttori/distruttori - C in ogni caso non li hanno :)

Per ottenere la memoria di dimensioni, è possibile utilizzare sizeof operatore.

Se si desidera lavorare con array multidimensionali, è necessario utilizzare più volte (come nuovo):

int** ptr_to_ptr = (int **) malloc(12 * sizeof(int *)); //assuming an array with length 12. 
ptr[0] = (int *) malloc(10 * sizeof(int)); //1st element is an array of 10 items 
ptr[1] = (int *) malloc(5 * sizeof(int)); //2nd element an array of 5 elements etc 
+4

In C non è necessario eseguire il cast da void * ad altri puntatori. È solo int * p = malloc (sizeof (int) * cElements); –

+0

Chris: Sei sicuro? Non ho lavorato con C per un po 'di tempo ormai, ma IIRC, ho dovuto farlo perché il tipo di ritorno di malloc è nullo *. –

+0

In c 'void *' converte automaticamente in altri tipi di puntatore. La trasmissione del ritorno di malloc può causare errori se non è stato incluso 'stdlib.h', poiché si suppone che i parametri siano' int'. –

2

uso/funzioni malloc liberi.

6

Si noti che i costruttori possono generare eccezioni in C++. L'equivalente di player* p = new player(); sarebbe qualcosa di simile in C.

struct player *p = malloc(sizeof *p); 
if (!p) handle_out_of_memory(); 
int err = construct_player(p); 
if (err) 
{ 
    free(p); 
    handle_constructor_error(); 
} 

L'equivalente di delete p è più semplice, perché i distruttori non dovrebbero mai "tiro".

destruct(p); 
free(p); 
+0

Come sarebbe 'construct_player'? –

5

Uso di new e delete in C++ combina due responsabilità - allocazione/rilascio memoria dinamica, e inizializzazione/rilascio di un oggetto.

Come tutte le altre risposte dicono, il modo più comune per allocare e rilasciare la memoria dinamica è chiamare malloc e free. È anche possibile utilizzare funzioni specifiche del sistema operativo per ottenere una grande quantità di memoria e allocare gli oggetti in questo, ma ciò è più raro - solo se si hanno requisiti abbastanza specifici che malloc non soddisfa.

In C, la maggior parte delle API fornirà una coppia di funzioni che soddisfano gli altri ruoli di new e delete.

Ad esempio, il file API utilizza una coppia di funzioni di apertura e chiusura:

// C++ 
fstream* fp = new fstream("c:\\test.txt", "r"); 
delete fp; 

// C 
FILE *fp=fopen("c:\\test.txt", "r"); 
fclose(fp); 

può essere che fopen utilizza malloc per allocare la memoria per la FILE struct, oppure può assegnare staticamente un tavolo per il numero massimo di puntatori di file all'avvio del processo. Il punto è che l'API non richiede che il client utilizzi malloc e free.

Altre API forniscono funzioni che eseguono solo l'inizializzazione e il rilascio di parte del contratto, equivalenti al costruttore e al distruttore, che consente al codice client di utilizzare l'archiviazione automatica, statica o dinamica.Un esempio è l'API pthreads:

pthread_t thread; 

pthread_create(&thread, NULL, thread_function, (void*) param); 

Questo permette al cliente una maggiore flessibilità, ma aumenta l'accoppiamento tra la biblioteca e il cliente - il cliente ha bisogno di conoscere la dimensione del tipo pthread_t, mentre se la libreria gestisce sia allocazione e inizializzazione il client non ha bisogno di conoscere la dimensione del tipo, quindi l'implementazione può variare senza cambiare il client. Né introduce tanto l'accoppiamento tra il client e l'implementazione come fa il C++. (Spesso è meglio pensare a C++ come un linguaggio di metaprogrammazione di template con vtables rispetto a un linguaggio OO)

+0

Puoi spiegare esattamente quali requisiti specifici malloc non soddisfa? – Pacerier

+0

@Pacerier 'malloc' alloca la memoria. 'operator new' (di solito) alloca la memoria * e * inizializza la memoria per contenere i valori forniti dal costruttore della classe dell'oggetto specificato. (c'è una variabile di 'operator new' chiamata 'placement new' che non alloca memoria, quindi puoi usare malloc per la prima parte e nuova per la seconda se lo desideri) –

Problemi correlati