c pointers initialization malloc variable-length-array

¿Cuál es la diferencia entre un VLA y una asignación de memoria dinámica a través de malloc?



pointers initialization (4)

Agregaré un poco de información en términos de administración de memoria, además de lo que otros dijeron.

1) La principal diferencia está aquí:

const int MAX_BUF = 1000; char* Buffer = malloc(MAX_BUF);

Debe administrar la memoria asignada manualmente, por ejemplo, Buffer libre cuando haya terminado de usarlo. Olvidar free (o liberarlo dos veces) puede ocasionar problemas.

2) Con el segundo caso:

char Buffer[MAX_BUF];

No necesitas liberar nada. Será destruido automáticamente. Por lo tanto, evita la tarea de manejar la memoria, lo cual es bueno. Debe intentar evaluar siempre qué enfoque necesita.

Algunos puntos.

  • Como el segundo se asigna en la pila, el primer enfoque también se toma cuando se necesita crear una gran matriz, ya que generalmente hay más memoria disponible en el montón.
  • Además, si crea una matriz utilizando un segundo enfoque, por ejemplo, en el método, el tiempo de vida del objeto será ese método; no podrá utilizar esa matriz fuera de ese método. Mientras que con la asignación dinámica ese no es el caso.

Tenía curiosidad con esto:

¿Cuál es la diferencia entre:

const int MAX_BUF = 1000; char* Buffer = malloc(MAX_BUF);

y:

char Buffer[MAX_BUF];


La diferencia más notable es el alcance. La matriz VLA solo será válida dentro del alcance donde se declara, mientras que una matriz dinámica estará disponible en todas partes del programa hasta que llame a free() .

En la práctica, los VLA pueden ser más rápidos que la memoria dinámica, en caso de que el compilador use la asignación de pila para el VLA. Sin embargo, no está especificado por el estándar C donde se asigna un VLA.

(En teoría, un compilador podría asignar un VLA en el montón, pero luego el compilador también sería responsable de la limpieza. No creo que existan soluciones de este tipo. Todos los compiladores que he usado siempre declaran los VLA en la pila. )

Esto significa que los VLA no son adecuados para almacenar grandes cantidades de datos: correría el riesgo de desbordamiento de pila. Sin embargo, esto no es una preocupación cuando usa memoria dinámica.

Los VLA no tienen la misma portabilidad que las matrices dinámicas, ya que los compiladores terriblemente antiguos no son compatibles con los VLA. En teoría, los nuevos compiladores de C11 tampoco tienen que admitir VLA, aunque en este momento sé que ningún compilador ha sido lo suficientemente estúpido como para abandonar ese soporte.

Comparación / resumen:

  • Los VLA deben usarse cuando hay pequeñas cantidades de datos locales, porque tienen un tiempo de asignación rápido y una limpieza automática.
  • Las matrices dinámicas deben usarse cuando hay grandes cantidades de datos, para evitar el desbordamiento de la pila.
  • Las matrices dinámicas se deben usar cuando los datos deben persistir después de la ejecución de una función y estar disponibles en otra parte del programa.
  • Las matrices dinámicas deben usarse cuando tenga requisitos de portabilidad excepcionales o irracionales.

char* Buffer = malloc(MAX_BUF);

crea un Buffer puntero de caracteres, asigna dinámicamente MAX_BUF bytes de memoria a través del malloc y hace que Buffer apunte al inicio del espacio asignado. Esta memoria se asigna en el montón.

char Buffer[MAX_BUF];

crea un Buffer de matriz de tamaño MAX_BUF que puede contener un máximo de MAX_BUF caracteres. Tenga en cuenta que está creando una VLA (una característica introducida en C99 ) ya que MAX_BUF es una variable. Esta matriz se puede crear en la pila.


  • Caso 1: en

    char Buffer[MAX_BUF];

    Buffer es una matriz de tamaño MAX_BUF . La técnica de asignación se llama VLA .

  • Caso 2: en

    const int MAX_BUF = 1000; char* Buffer = malloc(MAX_BUF);

    Buffer es un puntero al que se le asigna una memoria de tamaño MAX_BUF que es 1000 .

y, una matriz no es lo mismo que un puntero, y C-FAQ tiene una colección muy buena que detalla los motivos .

La principal diferencia, en términos de usabilidad y comportamiento son:

  1. (1) está en la pila, generalmente Nota , mientras que (2) está en el montón, siempre.
  2. (1) tiene un tamaño fijo una vez asignado, (2) se puede cambiar de tamaño.
  3. (1) se asigna cuando se llama a la función de cierre y tiene el alcance de bloque OTOH, (2) se asigna memoria dinámicamente, en tiempo de ejecución y la memoria devuelta tiene una vida útil que se extiende desde la asignación hasta la desasignación.
  4. (1) la memoria asignada no necesita ser administrada por el programador, mientras que en (2) toda la memoria malloc() d debe estar free() d. [ Cortesía: Giorgi ]

Nota: Wiki

Por ejemplo, el compilador C de GNU asigna memoria para VLA en la pila.