2010-04-10 19 views
7

¿Cuál es la diferencia entre¿Cuál es la diferencia entre alloca (n) y char x [n]?

void *bytes = alloca(size); 

y

char bytes[size]; //Or to be more precise, char x[size]; void *bytes = x; 

... donde tamaño es una variable cuyo valor es desconocido en tiempo de compilación.

+1

La respuesta depende críticamente de si 'size' es una constante en tiempo de compilación. ¿Lo es? – AnT

+0

no, el tamaño es, para todos los efectos, un argumento para la función –

+0

Eso no importa. Apple, por defecto, usa '--std = gnu99' que admite ambos. 'alloca()' es una extensión de GNU, y la matriz de longitud variable es una característica C99 que cumple con los estándares. –

Respuesta

13

alloca() no reclama memoria hasta que la función actual finaliza, mientras que la matriz de longitud variable recupera la memoria cuando finaliza el bloque actual.

Dicho de otra manera:

void foo() 
{ 
    size_t size = 42; 
    if (size) { 
     void *bytes1 = alloca(size); 
     char bytes2[size]; 
    } // bytes2 is deallocated here 
}; //bytes1 is deallocated here 

alloca() puede ser soportado (de manera) en cualquier compilador C89, mientras que la matriz de longitud variable requiere un compilador C99.

+2

@Billy: no se garantiza que la memoria asignada por bytes de bytes [tamaño] sea reclamada físicamente al final del bloque actual; sin embargo, el acceso después del bloque actual ya no es posible. – Vlad

+0

¿Qué compilador hace eso? –

+2

@Vlad: Técnicamente, el estándar C menciona muy poco acerca de dónde las cosas realmente necesitan almacenarse físicamente para evitar cualquier posible dependencia de una arquitectura en particular. Sin embargo, incluso si algo no está explícitamente en el estándar, el significado implícito en el estándar resulta en el 99.9% de los compiladores que lo implementan de esa manera. –

0

En la segunda forma, size debe ser una constante conocida para compilar el tiempo.

+3

No en C99. (15 chas) –

+0

@Billy: De hecho. – Vlad

+0

Posiblemente, pero es más probable que el OP se refiera a matrices de longitud variable, parte del estándar C99. – rjh

6

Desde el GNU documentation:

espacio asignado con alloca existe hasta que los contienen función devoluciones. El espacio para una matriz de longitud variable se desasigna en cuanto finaliza el alcance del nombre de la matriz. (Si utiliza ambas matrices de longitud variable y alloca en la misma función, desasignación de una matriz de longitud variable también desasignar nada más recientemente asignado con alloca.)

Además, alloca no es una función estándar de C, por lo que no se garantiza el soporte en todos los compiladores. Los arreglos de longitud variable son parte del estándar C99, por lo que cualquier compilador compatible con C99 debería implementarlo.

+0

Incluso si su compilador no lo admite, normalmente hay disponibles versiones de dominio público de 'alloca'. –

+0

tenga en cuenta que alloca() se especifica en POSIX.1-2001 – martinkunev

5

Además del punto mencionado por Billy, alloca no es estándar (ni siquiera está en C99).

0

Además de los puntos discutidos ya-de cuando exactamente se libera el espacio, y si el constructo está soportada en absoluto, también hay esto:

  • En el caso alloca, bytes tiene un tipo de puntero.
  • En el caso [], bytes tiene un tipo de matriz.

La diferencia más notable está en lo que sizeof(bytes) es; para un puntero es el tamaño del puntero (sizeof(void *)) mientras que para una matriz es el tamaño del espacio asignado (sizeof(char) * size, que = size para este caso desde sizeof(char) = 1).

(también, en su ejemplo, los tipos de elementos son diferentes;. A ser el mismo, el primero se debe cambiar a char *bytes = alloca(size))

0

La mayor diferencia es que alloca no llama constructores o destructores cuando se está usando la memoria como variables de clase.

Es menos probable que se noten las otras diferencias, pero pueden aparecer en algunos errores de tiempo de ejecución en algunas situaciones.

Cuestiones relacionadas