C

C

Tutorial C: Arrays dinámicos

Aprende a crear y gestionar arrays dinámicos en C usando malloc, realloc y matrices 2D para optimizar memoria y flexibilidad en tus programas.

Aprende C y certifícate

Crear arrays con malloc

En C, los arrays son estructuras que nos permiten almacenar múltiples elementos del mismo tipo bajo un único nombre. Hasta ahora, probablemente hayas trabajado con arrays de tamaño fijo, declarados en tiempo de compilación. Sin embargo, en muchas situaciones reales, necesitamos crear arrays cuyo tamaño se determina durante la ejecución del programa.

La función malloc (memory allocation) nos permite reservar memoria dinámicamente, es decir, en tiempo de ejecución. Esta función forma parte de la biblioteca estándar stdlib.h y es fundamental para crear arrays cuyo tamaño no conocemos hasta que el programa está en marcha.

Sintaxis básica

Para utilizar malloc, primero debemos incluir la biblioteca adecuada:

#include <stdlib.h>

La sintaxis básica para crear un array dinámico es:

tipo *nombre_array = (tipo *)malloc(numero_elementos * sizeof(tipo));

Donde:

  • tipo es el tipo de datos que almacenará el array (int, float, char, etc.)
  • nombre_array es el identificador que usaremos para referirnos al array
  • numero_elementos es la cantidad de elementos que queremos almacenar
  • sizeof(tipo) calcula el tamaño en bytes que ocupa cada elemento

Ejemplo práctico

Veamos un ejemplo sencillo donde creamos un array de enteros cuyo tamaño se decide en tiempo de ejecución:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int tamano;
    int *numeros;
    
    // Pedimos al usuario el tamaño del array
    printf("¿Cuántos números deseas almacenar? ");
    scanf("%d", &tamano);
    
    // Reservamos memoria para el array
    numeros = (int *)malloc(tamano * sizeof(int));
    
    // Verificamos si la asignación fue exitosa
    if (numeros == NULL) {
        printf("Error: No se pudo asignar memoria.\n");
        return 1;
    }
    
    // Llenamos el array con datos
    for (int i = 0; i < tamano; i++) {
        numeros[i] = i * 10;
    }
    
    // Mostramos el contenido del array
    printf("Contenido del array:\n");
    for (int i = 0; i < tamano; i++) {
        printf("numeros[%d] = %d\n", i, numeros[i]);
    }
    
    // Liberamos la memoria asignada
    free(numeros);
    
    return 0;
}

Puntos importantes a considerar

  1. Verificación de memoria: Siempre debemos comprobar si malloc pudo asignar la memoria solicitada. Si no hay suficiente memoria disponible, malloc devolverá NULL.
if (array == NULL) {
    printf("Error: No se pudo asignar memoria.\n");
    // Manejar el error apropiadamente
}
  1. Liberación de memoria: Es crucial liberar la memoria asignada con malloc cuando ya no la necesitemos, utilizando la función free(). No hacerlo provocará fugas de memoria (memory leaks).
free(array);  // Libera la memoria asignada
  1. Acceso a elementos: Podemos acceder a los elementos del array dinámico de la misma manera que con arrays normales, usando la notación de corchetes:
array[0] = 100;  // Asigna 100 al primer elemento
int valor = array[5];  // Obtiene el valor del sexto elemento

Ejemplo: Array de caracteres (string)

Los arrays de caracteres son especialmente útiles para manejar cadenas de texto de longitud variable:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main() {
    int longitud;
    char *texto;
    
    printf("¿Cuál es la longitud máxima del texto? ");
    scanf("%d", &longitud);
    
    // Reservamos espacio para los caracteres + el terminador nulo '\0'
    texto = (char *)malloc((longitud + 1) * sizeof(char));
    
    if (texto == NULL) {
        printf("Error: No se pudo asignar memoria.\n");
        return 1;
    }
    
    // Limpiamos el buffer de entrada
    while (getchar() != '\n');
    
    printf("Introduce un texto: ");
    fgets(texto, longitud + 1, stdin);
    
    // Eliminamos el salto de línea si existe
    if (texto[strlen(texto) - 1] == '\n') {
        texto[strlen(texto) - 1] = '\0';
    }
    
    printf("Has introducido: %s\n", texto);
    
    // Liberamos la memoria
    free(texto);
    
    return 0;
}

Inicialización de arrays dinámicos

A diferencia de los arrays estáticos, los arrays dinámicos no se inicializan automáticamente a cero. Si necesitamos inicializar todos los elementos a cero, podemos usar la función calloc en lugar de malloc:

int *numeros = (int *)calloc(tamano, sizeof(int));

Alternativamente, podemos inicializar manualmente después de usar malloc:

int *numeros = (int *)malloc(tamano * sizeof(int));
if (numeros != NULL) {
    for (int i = 0; i < tamano; i++) {
        numeros[i] = 0;  // Inicializa cada elemento a 0
    }
}

Uso práctico: Almacenamiento de datos de entrada

Un caso de uso común es cuando necesitamos almacenar datos cuya cantidad no conocemos de antemano:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int capacidad = 5;  // Capacidad inicial
    int *datos = (int *)malloc(capacidad * sizeof(int));
    int contador = 0;
    int numero;
    
    if (datos == NULL) {
        printf("Error: No se pudo asignar memoria.\n");
        return 1;
    }
    
    printf("Introduce números (0 para terminar):\n");
    
    while (1) {
        scanf("%d", &numero);
        
        if (numero == 0) {
            break;  // Salimos del bucle si se introduce 0
        }
        
        // Almacenamos el número
        datos[contador] = numero;
        contador++;
        
        // Aquí normalmente verificaríamos si necesitamos más espacio
        // (esto se verá en la sección de realloc)
    }
    
    printf("Has introducido %d números:\n", contador);
    for (int i = 0; i < contador; i++) {
        printf("%d ", datos[i]);
    }
    printf("\n");
    
    free(datos);
    return 0;
}

Consideraciones de rendimiento

Cuando trabajamos con arrays dinámicos, es importante tener en cuenta:

  • La fragmentación de memoria puede ocurrir si asignamos y liberamos memoria frecuentemente.
  • Las operaciones de asignación de memoria tienen un coste computacional, por lo que es mejor asignar bloques grandes de una vez que muchos bloques pequeños.
  • Siempre debemos liberar la memoria cuando ya no la necesitemos para evitar fugas de memoria.

Los arrays dinámicos son una herramienta poderosa que nos permite utilizar la memoria de manera más eficiente, adaptando nuestros programas a las necesidades reales de cada ejecución en lugar de reservar siempre el peor caso posible.

Redimensionar con realloc

Una de las ventajas principales de los arrays dinámicos es la posibilidad de cambiar su tamaño durante la ejecución del programa. Cuando trabajamos con datos cuya cantidad no conocemos de antemano o que puede variar, necesitamos una forma de ajustar el tamaño de nuestros arrays según sea necesario.

La función realloc nos permite redimensionar un bloque de memoria previamente asignado con malloc o calloc. Esta función forma parte de la biblioteca stdlib.h y es fundamental para gestionar arrays dinámicos de manera eficiente.

Sintaxis básica

La sintaxis para usar realloc es:

ptr = (tipo *)realloc(ptr, nuevo_tamaño);

Donde:

  • ptr es el puntero a la memoria previamente asignada
  • tipo es el tipo de datos del array
  • nuevo_tamaño es el tamaño total en bytes del nuevo bloque de memoria

Para un array, normalmente calculamos el nuevo tamaño multiplicando el número de elementos por el tamaño de cada elemento:

array = (int *)realloc(array, nueva_cantidad * sizeof(int));

Comportamiento de realloc

La función realloc tiene un comportamiento interesante que debemos entender:

  • Si ptr es NULL, realloc actúa como malloc y asigna un nuevo bloque de memoria.
  • Si nuevo_tamaño es 0, realloc actúa como free y libera la memoria.
  • Si hay suficiente espacio en la ubicación actual, simplemente expande el bloque existente.
  • Si no hay suficiente espacio, realloc:
  1. Asigna un nuevo bloque de memoria del tamaño solicitado
  2. Copia los datos del bloque antiguo al nuevo
  3. Libera el bloque antiguo
  4. Devuelve un puntero al nuevo bloque

Ejemplo básico: Ampliar un array

Veamos un ejemplo donde ampliamos un array de enteros:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *numeros;
    int tamano_inicial = 5;
    int tamano_nuevo = 10;
    
    // Asignamos memoria para el array inicial
    numeros = (int *)malloc(tamano_inicial * sizeof(int));
    
    if (numeros == NULL) {
        printf("Error: No se pudo asignar memoria.\n");
        return 1;
    }
    
    // Inicializamos el array
    for (int i = 0; i < tamano_inicial; i++) {
        numeros[i] = i * 10;
    }
    
    // Mostramos el array inicial
    printf("Array inicial:\n");
    for (int i = 0; i < tamano_inicial; i++) {
        printf("%d ", numeros[i]);
    }
    printf("\n");
    
    // Redimensionamos el array
    numeros = (int *)realloc(numeros, tamano_nuevo * sizeof(int));
    
    if (numeros == NULL) {
        printf("Error: No se pudo redimensionar el array.\n");
        return 1;
    }
    
    // Inicializamos los nuevos elementos
    for (int i = tamano_inicial; i < tamano_nuevo; i++) {
        numeros[i] = i * 10;
    }
    
    // Mostramos el array ampliado
    printf("Array ampliado:\n");
    for (int i = 0; i < tamano_nuevo; i++) {
        printf("%d ", numeros[i]);
    }
    printf("\n");
    
    // Liberamos la memoria
    free(numeros);
    
    return 0;
}

Precauciones importantes

Al usar realloc, debemos tener en cuenta algunas precauciones importantes:

  1. Verificar el resultado: Siempre debemos comprobar si realloc pudo asignar la memoria solicitada:
int *temp = (int *)realloc(array, nuevo_tamano * sizeof(int));
if (temp != NULL) {
    array = temp;  // Solo actualizamos si la asignación fue exitosa
} else {
    // Manejar el error, pero conservamos el array original
    printf("Error: No se pudo redimensionar el array.\n");
}
  1. Preservar el puntero original: Es recomendable usar un puntero temporal para la reasignación, ya que si realloc falla, devuelve NULL pero no libera la memoria original.

  2. Contenido después de redimensionar:

  • Si ampliamos el array, los elementos originales se conservan.
  • Los nuevos elementos tendrán valores indeterminados.
  • Si reducimos el array, los elementos que no caben se pierden.

Ejemplo práctico: Array dinámico que crece según necesidad

Un caso de uso común es crear un array que crece automáticamente cuando necesitamos añadir más elementos:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int *numeros = NULL;
    int capacidad = 0;
    int tamano = 0;
    int numero;
    
    printf("Introduce números (0 para terminar):\n");
    
    while (1) {
        scanf("%d", &numero);
        
        if (numero == 0) {
            break;
        }
        
        // Si hemos alcanzado la capacidad, ampliamos el array
        if (tamano >= capacidad) {
            // Calculamos la nueva capacidad (duplicamos o iniciamos con 4)
            int nueva_capacidad = capacidad == 0 ? 4 : capacidad * 2;
            
            // Usamos un puntero temporal para la redimensión
            int *temp = (int *)realloc(numeros, nueva_capacidad * sizeof(int));
            
            if (temp == NULL) {
                printf("Error: No se pudo ampliar el array.\n");
                free(numeros);  // Liberamos la memoria existente
                return 1;
            }
            
            numeros = temp;
            capacidad = nueva_capacidad;
            printf("Array ampliado a %d elementos.\n", capacidad);
        }
        
        // Añadimos el nuevo número
        numeros[tamano] = numero;
        tamano++;
    }
    
    // Mostramos los números introducidos
    printf("\nHas introducido %d números:\n", tamano);
    for (int i = 0; i < tamano; i++) {
        printf("%d ", numeros[i]);
    }
    printf("\n");
    
    // Ajustamos el tamaño final para no desperdiciar memoria
    if (tamano > 0) {
        numeros = (int *)realloc(numeros, tamano * sizeof(int));
    }
    
    // Liberamos la memoria
    free(numeros);
    
    return 0;
}

Estrategias de crecimiento

Cuando implementamos arrays dinámicos que crecen, es importante considerar la estrategia de crecimiento:

  • Crecimiento lineal: Añadir un número fijo de elementos cada vez (por ejemplo, 10 más).
  • Crecimiento exponencial: Multiplicar la capacidad (por ejemplo, duplicar).

El crecimiento exponencial es generalmente más eficiente porque reduce el número de operaciones de reasignación. Si añadimos elementos uno a uno con crecimiento lineal, la complejidad temporal sería O(n²), mientras que con crecimiento exponencial sería O(n).

// Crecimiento lineal (menos eficiente)
nueva_capacidad = capacidad + 10;

// Crecimiento exponencial (más eficiente)
nueva_capacidad = capacidad == 0 ? 4 : capacidad * 2;

Reducción de un array

También podemos usar realloc para reducir el tamaño de un array cuando ya no necesitamos toda la memoria asignada:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int tamano_inicial = 10;
    int tamano_reducido = 5;
    int *array = (int *)malloc(tamano_inicial * sizeof(int));
    
    if (array == NULL) {
        printf("Error: No se pudo asignar memoria.\n");
        return 1;
    }
    
    // Inicializamos el array
    for (int i = 0; i < tamano_inicial; i++) {
        array[i] = i + 1;
    }
    
    printf("Array original (%d elementos):\n", tamano_inicial);
    for (int i = 0; i < tamano_inicial; i++) {
        printf("%d ", array[i]);
    }
    printf("\n");
    
    // Reducimos el tamaño del array
    array = (int *)realloc(array, tamano_reducido * sizeof(int));
    
    if (array == NULL) {
        printf("Error: No se pudo redimensionar el array.\n");
        return 1;
    }
    
    printf("Array reducido (%d elementos):\n", tamano_reducido);
    for (int i = 0; i < tamano_reducido; i++) {
        printf("%d ", array[i]);
    }
    printf("\n");
    
    free(array);
    return 0;
}

Uso eficiente de la memoria

Redimensionar arrays nos permite hacer un uso eficiente de la memoria:

  1. Podemos empezar con arrays pequeños y ampliarlos según sea necesario.
  2. Podemos reducir arrays cuando ya no necesitamos tanto espacio.
  3. Evitamos desperdiciar memoria reservando solo lo que realmente necesitamos.

Este enfoque es especialmente útil cuando trabajamos con grandes cantidades de datos o en sistemas con recursos limitados.

Arrays 2D dinámicos básicos

Los arrays bidimensionales (o matrices) son estructuras que organizan datos en filas y columnas, formando una cuadrícula. Mientras que en C podemos declarar matrices estáticas fácilmente con int matriz[3][4], crear matrices dinámicas requiere un enfoque diferente utilizando punteros y asignación de memoria.

La creación de arrays 2D dinámicos es especialmente útil cuando necesitamos matrices cuyo tamaño se determina durante la ejecución del programa, o cuando trabajamos con matrices muy grandes que podrían sobrecargar la pila de memoria.

Enfoque básico: Array de punteros

El método más común para crear un array 2D dinámico en C es mediante un array de punteros. Este enfoque consiste en:

  1. Crear un array dinámico de punteros (para las filas)
  2. Para cada puntero de fila, asignar memoria para sus columnas

Veamos cómo implementarlo paso a paso:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int filas, columnas;
    int **matriz;
    
    // Solicitamos dimensiones al usuario
    printf("Introduce el número de filas: ");
    scanf("%d", &filas);
    printf("Introduce el número de columnas: ");
    scanf("%d", &columnas);
    
    // Paso 1: Asignamos memoria para el array de punteros (filas)
    matriz = (int **)malloc(filas * sizeof(int *));
    
    if (matriz == NULL) {
        printf("Error: No se pudo asignar memoria para las filas.\n");
        return 1;
    }
    
    // Paso 2: Asignamos memoria para cada fila (columnas)
    for (int i = 0; i < filas; i++) {
        matriz[i] = (int *)malloc(columnas * sizeof(int));
        
        if (matriz[i] == NULL) {
            printf("Error: No se pudo asignar memoria para la fila %d.\n", i);
            
            // Liberamos la memoria ya asignada
            for (int j = 0; j < i; j++) {
                free(matriz[j]);
            }
            free(matriz);
            
            return 1;
        }
    }
    
    // Ahora podemos usar la matriz normalmente
    printf("Inicializando matriz con valores de ejemplo...\n");
    
    // Llenamos la matriz con valores de ejemplo
    for (int i = 0; i < filas; i++) {
        for (int j = 0; j < columnas; j++) {
            matriz[i][j] = i * columnas + j;
        }
    }
    
    // Mostramos la matriz
    printf("Contenido de la matriz %dx%d:\n", filas, columnas);
    for (int i = 0; i < filas; i++) {
        for (int j = 0; j < columnas; j++) {
            printf("%3d ", matriz[i][j]);
        }
        printf("\n");
    }
    
    // Liberamos la memoria (importante: en orden inverso a la asignación)
    for (int i = 0; i < filas; i++) {
        free(matriz[i]);
    }
    free(matriz);
    
    return 0;
}

Acceso a los elementos

Una vez creada la matriz dinámica, podemos acceder a sus elementos usando la notación de corchetes dobles habitual:

// Asignar un valor
matriz[2][3] = 42;

// Leer un valor
int valor = matriz[1][4];

Internamente, C traduce matriz[i][j] a *(*(matriz + i) + j), lo que significa:

  1. Obtener el puntero a la fila i: matriz + i
  2. Obtener el contenido de ese puntero (la dirección de la fila): *(matriz + i)
  3. Avanzar j elementos en esa fila: *(matriz + i) + j
  4. Obtener el contenido de esa dirección: *(*(matriz + i) + j)

Liberación de memoria

La liberación de memoria para matrices dinámicas debe hacerse en orden inverso a la asignación:

// Primero liberamos cada fila
for (int i = 0; i < filas; i++) {
    free(matriz[i]);
}

// Después liberamos el array de punteros
free(matriz);

Es crucial liberar la memoria en este orden para evitar fugas de memoria. Si liberáramos primero el array de punteros, perderíamos las referencias a las filas y no podríamos liberarlas después.

Ejemplo práctico: Matriz de calificaciones

Veamos un ejemplo más práctico donde usamos una matriz dinámica para almacenar calificaciones de estudiantes:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int num_estudiantes, num_asignaturas;
    float **calificaciones;
    float *promedios;
    
    // Solicitamos información
    printf("Número de estudiantes: ");
    scanf("%d", &num_estudiantes);
    printf("Número de asignaturas: ");
    scanf("%d", &num_asignaturas);
    
    // Creamos la matriz de calificaciones
    calificaciones = (float **)malloc(num_estudiantes * sizeof(float *));
    if (calificaciones == NULL) {
        printf("Error: No se pudo asignar memoria.\n");
        return 1;
    }
    
    for (int i = 0; i < num_estudiantes; i++) {
        calificaciones[i] = (float *)malloc(num_asignaturas * sizeof(float));
        if (calificaciones[i] == NULL) {
            printf("Error: No se pudo asignar memoria.\n");
            // Liberamos memoria ya asignada
            for (int j = 0; j < i; j++) {
                free(calificaciones[j]);
            }
            free(calificaciones);
            return 1;
        }
    }
    
    // Array para almacenar promedios
    promedios = (float *)malloc(num_estudiantes * sizeof(float));
    if (promedios == NULL) {
        printf("Error: No se pudo asignar memoria para promedios.\n");
        // Liberamos memoria de la matriz
        for (int i = 0; i < num_estudiantes; i++) {
            free(calificaciones[i]);
        }
        free(calificaciones);
        return 1;
    }
    
    // Ingresamos las calificaciones
    for (int i = 0; i < num_estudiantes; i++) {
        printf("Calificaciones del estudiante %d:\n", i + 1);
        float suma = 0;
        
        for (int j = 0; j < num_asignaturas; j++) {
            printf("  Asignatura %d: ", j + 1);
            scanf("%f", &calificaciones[i][j]);
            suma += calificaciones[i][j];
        }
        
        promedios[i] = suma / num_asignaturas;
    }
    
    // Mostramos resultados
    printf("\nResumen de calificaciones:\n");
    printf("Estudiante | ");
    for (int j = 0; j < num_asignaturas; j++) {
        printf("Asig.%d  ", j + 1);
    }
    printf("| Promedio\n");
    printf("----------|");
    for (int j = 0; j < num_asignaturas; j++) {
        printf("---------|");
    }
    printf("|--------\n");
    
    for (int i = 0; i < num_estudiantes; i++) {
        printf("%10d | ", i + 1);
        for (int j = 0; j < num_asignaturas; j++) {
            printf("%7.2f | ", calificaciones[i][j]);
        }
        printf("%7.2f\n", promedios[i]);
    }
    
    // Liberamos memoria
    for (int i = 0; i < num_estudiantes; i++) {
        free(calificaciones[i]);
    }
    free(calificaciones);
    free(promedios);
    
    return 0;
}

Matrices de tamaño variable por fila

Una ventaja de los arrays 2D dinámicos es que podemos tener filas de diferentes longitudes, algo imposible con matrices estáticas:

#include <stdio.h>
#include <stdlib.h>

int main() {
    int num_filas;
    int **matriz;
    int *longitudes_filas;
    
    printf("Número de filas: ");
    scanf("%d", &num_filas);
    
    // Asignamos memoria para el array de punteros
    matriz = (int **)malloc(num_filas * sizeof(int *));
    
    // Array para almacenar la longitud de cada fila
    longitudes_filas = (int *)malloc(num_filas * sizeof(int));
    
    if (matriz == NULL || longitudes_filas == NULL) {
        printf("Error: No se pudo asignar memoria.\n");
        free(matriz);
        free(longitudes_filas);
        return 1;
    }
    
    // Para cada fila, preguntamos su longitud y asignamos memoria
    for (int i = 0; i < num_filas; i++) {
        printf("Longitud de la fila %d: ", i + 1);
        scanf("%d", &longitudes_filas[i]);
        
        matriz[i] = (int *)malloc(longitudes_filas[i] * sizeof(int));
        
        if (matriz[i] == NULL) {
            printf("Error: No se pudo asignar memoria para la fila %d.\n", i + 1);
            // Liberamos memoria ya asignada
            for (int j = 0; j < i; j++) {
                free(matriz[j]);
            }
            free(matriz);
            free(longitudes_filas);
            return 1;
        }
        
        // Llenamos la fila con valores
        printf("Introduce %d valores para la fila %d:\n", longitudes_filas[i], i + 1);
        for (int j = 0; j < longitudes_filas[i]; j++) {
            scanf("%d", &matriz[i][j]);
        }
    }
    
    // Mostramos la matriz irregular
    printf("\nMatriz con filas de diferentes longitudes:\n");
    for (int i = 0; i < num_filas; i++) {
        printf("Fila %d: ", i + 1);
        for (int j = 0; j < longitudes_filas[i]; j++) {
            printf("%d ", matriz[i][j]);
        }
        printf("\n");
    }
    
    // Liberamos memoria
    for (int i = 0; i < num_filas; i++) {
        free(matriz[i]);
    }
    free(matriz);
    free(longitudes_filas);
    
    return 0;
}

Consideraciones de rendimiento

Al trabajar con matrices dinámicas, hay algunos aspectos a considerar para optimizar el rendimiento:

  • Localidad de memoria: Las matrices creadas con el enfoque de array de punteros no garantizan que las filas estén contiguas en memoria, lo que puede afectar al rendimiento debido a fallos de caché.

  • Fragmentación: La asignación de múltiples bloques pequeños puede causar fragmentación de memoria.

  • Sobrecarga de gestión: Cada llamada a malloc tiene una pequeña sobrecarga, por lo que crear muchas filas individualmente puede ser menos eficiente que un único bloque grande.

Los arrays 2D dinámicos son una herramienta fundamental cuando necesitamos flexibilidad en el tamaño de nuestras matrices o cuando trabajamos con matrices demasiado grandes para la pila. Aunque requieren una gestión de memoria más cuidadosa, nos ofrecen la capacidad de adaptar nuestros programas a las necesidades reales de cada ejecución.

CONSTRUYE TU CARRERA EN IA Y PROGRAMACIÓN SOFTWARE

Accede a +1000 lecciones y cursos con certificado. Mejora tu portfolio con certificados de superación para tu CV.

30 % DE DESCUENTO

Plan mensual

19.00 /mes

13.30 € /mes

Precio normal mensual: 19 €
63 % DE DESCUENTO

Plan anual

10.00 /mes

7.00 € /mes

Ahorras 144 € al año
Precio normal anual: 120 €
Aprende C online

Todas las lecciones de C

Accede a todas las lecciones de C y aprende con ejemplos prácticos de código y ejercicios de programación con IDE web sin instalar nada.

Accede GRATIS a C y certifícate

En esta lección

Objetivos de aprendizaje de esta lección

  • Comprender cómo crear arrays dinámicos en C usando malloc.
  • Aprender a redimensionar arrays dinámicos con realloc de forma segura.
  • Gestionar correctamente la memoria dinámica, incluyendo la liberación con free.
  • Implementar arrays bidimensionales dinámicos mediante arrays de punteros.
  • Conocer las consideraciones de rendimiento y estrategias para el uso eficiente de memoria dinámica.