Asignación dinámica de estructuras
Parte de la sección Logic & Flow del Journey de C de Coddy — lección 48 de 63.
Hasta ahora, has aprendido cómo crear structs en la pila (stack): existen dentro del ámbito (scope) donde se declaran y se limpian automáticamente cuando ese ámbito termina. Pero, ¿qué pasa si necesitas que un struct persista más allá de su ámbito original, o cuando no sabes en tiempo de compilación cuántos structs necesitarás?
Aquí es donde entra en juego la asignación dinámica. Puedes usar malloc() para crear estructuras en el heap, al igual que lo harías para cualquier otro tipo de dato. La diferencia clave es que las estructuras asignadas dinámicamente permanecen en memoria hasta que las liberes explícitamente con free().
Aquí tienes la sintaxis para asignar dinámicamente un struct:
struct Point *ptr = malloc(sizeof(struct Point));Esto asigna suficiente memoria en el heap para contener una estructura Point y devuelve un puntero a esa memoria. Luego puedes usar el operador flecha para acceder y modificar los miembros de la estructura:
ptr->x = 10;
ptr->y = 20;Recuerda comprobar siempre si malloc() tuvo éxito (devolvió un valor distinto de NULL) y llamar a free(ptr) cuando hayas terminado con la estructura para evitar fugas de memoria. Esta técnica es esencial para crear programas flexibles que puedan crear y gestionar estructuras de datos en tiempo de ejecución.
Desafío
FácilCrea un programa en C que demuestre la asignación dinámica de estructuras utilizando malloc(). Tu programa debe:
- Definir un
structllamadoCarcon los siguientes miembros:- Un entero
yearpara almacenar el año de fabricación - Un arreglo de caracteres
brandcon tamaño 20 para almacenar la marca del coche - Un arreglo de caracteres
modelcon tamaño 25 para almacenar el modelo del coche - Un flotante
pricepara almacenar el precio del coche - Un entero
mileagepara almacenar el kilometraje del coche
- Un entero
- En la función principal, declarar un puntero a una estructura
CarllamadocarPtr - Usar
malloc()para asignar dinámicamente memoria para una estructuraCary asignar la dirección devuelta acarPtr - Verificar si la asignación de memoria fue exitosa:
- Si
carPtresNULL, imprimirMemory allocation failedy salir del programa - Si la asignación tuvo éxito, imprimir
Memory allocation successful
- Si
- Leer los siguientes valores de entrada y asignarlos a los miembros de la estructura utilizando el operador de flecha:
- Leer un entero para el año y asignarlo usando
carPtr->year - Leer una cadena para la marca y asignarla usando
carPtr->brand - Leer una cadena para el modelo y asignarla usando
carPtr->model - Leer un flotante para el precio y asignarlo usando
carPtr->price - Leer un entero para el kilometraje y asignarlo usando
carPtr->mileage
- Leer un entero para el año y asignarlo usando
- Después de leer todos los valores, realizar los siguientes cálculos utilizando el operador de flecha:
- Calcular la edad del coche restando el año de 2024:
int age = 2024 - carPtr->year; - Calcular la tasa de depreciación basada en la edad: si la edad es mayor a 10, establecer la depreciación en 0.6, de lo contrario establecerla en 0.8
- Calcular el valor actual:
carPtr->price * depreciation
- Calcular la edad del coche restando el año de 2024:
- Imprimir la información del coche utilizando el operador de flecha en este formato exacto:
Car Information:Year: [year]Brand: [brand]Model: [model]Original Price: [price]Mileage: [mileage]Age: [age] yearsCurrent Value: [current_value]
- Liberar la memoria asignada dinámicamente usando
free(carPtr) - Imprimir
Memory freed successfully
Este desafío pone a prueba tu comprensión de la asignación dinámica de estructuras usando malloc(), la verificación de fallos en la asignación, el acceso a miembros de estructuras a través de punteros usando el operador de flecha y la liberación adecuada de la memoria asignada con free(). Practicarás el ciclo de vida completo de la gestión dinámica de memoria con estructuras.
Hoja de referencia
Usa malloc() para asignar estructuras dinámicamente en el heap:
struct Point *ptr = malloc(sizeof(struct Point));Accede a los miembros de la estructura a través de punteros utilizando el operador flecha:
ptr->x = 10;
ptr->y = 20;Comprueba siempre si malloc() tuvo éxito y libera la memoria cuando hayas terminado:
if (ptr == NULL) {
// Manejar el fallo de asignación
}
// Usar la estructura...
free(ptr);Pruébalo tú mismo
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// TODO: Definir la estructura Car aquí
int main() {
// TODO: Declarar un puntero a la estructura Car llamado carPtr
// TODO: Usar malloc() para asignar memoria para una estructura Car
// TODO: Verificar si la asignación de memoria fue exitosa
// Leer los valores de entrada
int year, mileage;
char brand[20], model[25];
float price;
scanf("%d", &year);
scanf("%s", brand);
scanf("%s", model);
scanf("%f", &price);
scanf("%d", &mileage);
// TODO: Asignar los valores de entrada a los miembros de la estructura usando el operador de flecha
// TODO: Calcular la edad, la depreciación y el valor actual
// TODO: Imprimir la información del coche en el formato requerido
// TODO: Liberar la memoria asignada e imprimir un mensaje de éxito
return 0;
}Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Logic & Flow
1Fundamentos de Punteros
¿Qué es un puntero?Declaración de punterosEl operador de dirección (&)El operador de desreferencia (*)Punteros NULLResumen: Conceptos básicos de punteros4Proyecto: Utilidad de texto simple
Descripción general del proyectoContar caracteres2Punteros y Arrays
Nombres de Arrays como PunterosElementos de un Array - PunterosAritmética de PunterosComparación de PunterosResumen: Recorrido de Arrays con Punteros5Punteros y funciones
Paso por valorPasar punteros a funcionesModificar variables mediante punterosUn ejemplo clásico: Intercambio (Swap)Pasar arrays a funcionesResumen: Argumentos de punteros a funciones8Estructuras y Punteros
Punteros a estructurasEl operador flecha (->)Pasar estructuras por valorPasar punteros a estructurasAsignación dinámica de estructurasResumen: Modificar estructuras - Ptr3Arreglos de caracteres y cadenas
Cadenas como arreglos de charEl terminador nuloEntrada de cadenas con scanfUso de strlen()Uso de strcpy()Uso de strcat()Uso de strcmp()Resumen: Funciones básicas de cadenas