2010-05-15 23 views

Respuesta

32

No hay expresión new/delete en C.

El equivalente más cercano es el malloc and free functions, si se ignoran los constructores/destructores y la seguridad de tipos.

#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: * Does 'sizeof (* p)' en realidad desreferencia 'p', ¿o es completamente equivalente a escribir' sizeof (int) '? Parece que en el primer caso, esta expresión podría causar una falla de segmentación (porque 'p 'aún no está asignada en este punto). En el último caso, probablemente preferiría escribir 'sizeof (int)' porque hay menos posibilidades de malinterpretar lo que hace esta afirmación. – stakx

+5

@stakx: el operador 'sizeof' se evalúa en tiempo de compilación. No hay desreferenciación. 'sizeof (* p)' es preferible a 'sizeof (int)' porque si cambia el tipo de 'p' a' double', el compilador no puede advertirle sobre la discrepancia de tamaño. – kennytm

+8

@stakx El operador 'sizeof' es una asignación de ** tipo ** a' tamaño_t'. El ** valor ** de su operando no es interesante en absoluto. Por ejemplo, en 'sizeof (1 + 2)', no hay absolutamente ninguna necesidad de calcular el resultado '3'. El operador 'sizeof' simplemente ve una expresión de tipo' int + int' e infiere que el resultado es también 'int'. Luego asigna 'int' a 4 (o 2 u 8, dependiendo de la plataforma). Es lo mismo con 'sizeof (* p)'. El sistema de tipos sabe que, en el nivel de tipo, la desreferenciación de un 'int *' produce un 'int'. 'sizeof' no está interesado en absoluto en el valor de' * p', solo importa el tipo. – fredoverflow

3

No es una réplica exacta pero los equivalentes compatibles son malloc y libres.

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

No hay constructores/destructores - C de todas formas no tenerlos :)

Para obtener el tamaño de la memoria, puede utilizar sizeof operador.

Si desea trabajar con matrices multidimensionales, que tendrá que utilizar varias veces (como nuevo):

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

En C, no es necesario emitir desde el vacío * a otros punteros. Es solo int * p = malloc (sizeof (int) * cElements); –

+0

Chris: ¿Estás seguro? No he trabajado con C desde hace bastante tiempo, pero IIRC, tuve que hacerlo porque el tipo de devolución de malloc es nulo *. –

+0

En c 'void *' se convierte automáticamente a otros tipos de punteros. Lanzar el retorno de malloc puede causar errores si no ha incluido 'stdlib.h', ya que se supondrá que los parámetros son' int'. –

2

Use malloc/funciones gratuitas.

6

Tenga en cuenta que los constructores pueden lanzar excepciones en C++. El equivalente de player* p = new player(); sería algo como esto en 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(); 
} 

el equivalente de delete p es más sencilla, ya que los destructores no debe "tirar".

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

¿Cómo sería 'build_player'? –

5

El uso de new y delete en C++ combina dos responsabilidad - la asignación/liberación de la memoria dinámica, y la inicialización/liberación de un objeto.

Como dicen todas las otras respuestas, la forma más común de asignar y liberar memoria dinámica es llamando al malloc y free. También puede usar funciones específicas del sistema operativo para obtener una gran cantidad de memoria y asignar sus objetos a eso, pero eso es más raro, solo si tiene requisitos bastante específicos que malloc no satisface.

En C, la mayoría de las API proporcionará un par de funciones que cumplen los otros roles de new y delete.

Por ejemplo, la API de archivo utiliza un par de funciones de apertura y cierre:

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

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

puede ser que fopen utiliza malloc para asignar el almacenamiento para el FILE struct, o puede asignar estáticamente una mesa para la cantidad máxima de punteros de archivo en el inicio del proceso. El punto es que la API no requiere que el cliente use malloc y free.

Otras API proporcionan funciones que solo realizan la inicialización y liberación de parte del contrato, equivalente al constructor y destructor, que permite que el código del cliente use almacenamiento automático, estático o dinámico.Un ejemplo es el pthreads API:

pthread_t thread; 

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

Esto permite al cliente una mayor flexibilidad, pero aumenta el acoplamiento entre la biblioteca y el cliente - el cliente necesita saber el tamaño del tipo pthread_t, mientras que si la biblioteca se encarga tanto asignación e inicialización, el cliente no necesita saber el tamaño del tipo, por lo que la implementación puede variar sin cambiar el cliente en absoluto. Ninguno de los dos introduce tanto acoplamiento entre el cliente y la implementación como lo hace C++. (A menudo es mejor pensar en C++ como un lenguaje de metaprogramación de plantillas con tablas que en un lenguaje OO)

+0

¿Puede explicar exactamente cuáles son los requisitos específicos que malloc no satisface? – Pacerier

+0

@Pacerier 'malloc' asigna memoria. 'operator new' (normalmente) asigna memoria * y * inicializa la memoria para contener los valores proporcionados por el constructor de la clase de objeto especificada. (hay una variable de 'operator new' llamada 'placement new' que no asigna memoria, por lo que puede usar malloc para la primera parte y nueva para la segunda si así lo desea) –

Cuestiones relacionadas