Menu
Coddy logo textTech

Inicialización en Stack

Parte de la sección Object Oriented Programming del Journey de C de Coddy — lección 14 de 61.

No todos los objetos necesitan residir en el heap. Cuando un struct es pequeño y tiene un tiempo de vida corto, asignarlo en el stack es más sencillo y rápido: sin malloc, sin free y sin riesgo de fugas de memoria.

En lugar de devolver un puntero, una función de fábrica puede devolver el struct por valor. El struct completo se copia al llamador:

typedef struct {
    int x;
    int y;
} Point;

Point create_point(int x, int y) {
    Point p;
    p.x = x;
    p.y = y;
    return p;
}

El llamador recibe una copia completamente inicializada:

Point origin = create_point(0, 0);
Point cursor = create_point(100, 50);
printf("Cursor: (%d, %d)\n", cursor.x, cursor.y);

Sin punteros, no se requiere limpieza. Cuando origin y cursor salen de ámbito, se destruyen automáticamente.

Este enfoque funciona mejor para structs pequeñas sin miembros asignados dinámicamente. Para objetos más grandes o aquellos que contienen punteros a la memoria heap, el patrón de constructor con malloc sigue siendo la mejor opción.

challenge icon

Desafío

Fácil

Vamos a construir un módulo Temperature que crea lecturas de temperatura en el stack utilizando una función de fábrica (factory function). A diferencia de los constructores basados en el heap de lecciones anteriores, este enfoque devuelve la estructura por valor: sin malloc, sin free, solo una asignación en el stack simple y eficiente.

Crearás tres archivos:

  • temperature.h: Declara una estructura Temperature con dos miembros: double celsius y char scale (para almacenar 'C' para Celsius). También declara dos funciones:
    • create_temperature — toma un valor double y devuelve una estructura Temperature por valor (¡no un puntero!)
    • temperature_to_fahrenheit — toma un const Temperature * y devuelve la temperatura equivalente en Fahrenheit como un double
    Usa guardas de inclusión con el símbolo TEMPERATURE_H.
  • temperature.c: Implementa ambas funciones. Tu función de fábrica debe crear una variable local Temperature, inicializar sus campos (establece scale a 'C') y devolverla. La fórmula de conversión es: fahrenheit = celsius * 9.0 / 5.0 + 32.0
  • main.c: Usa tu función de fábrica para crear una lectura de temperatura y mostrar tanto el valor en Celsius como en Fahrenheit.

Recibirás una entrada: la temperatura en Celsius (como un double).

En tu archivo principal, usa create_temperature para crear una estructura Temperature con el valor dado. Luego imprime el valor original en Celsius y su equivalente en Fahrenheit.

Imprime la salida en este formato:

Celsius: {celsius}
Fahrenheit: {fahrenheit}

Usa %.2f para ambos valores para mostrar dos decimales.

Por ejemplo, con una entrada de 25.0, la salida sería:

Celsius: 25.00
Fahrenheit: 77.00

Observa lo limpio que es este enfoque: recibes una estructura completamente inicializada sin preocupaciones de gestión de memoria. Cuando tu variable Temperature sale de su ámbito (scope), se limpia automáticamente.

Hoja de referencia

Las funciones de fábrica pueden devolver structs por valor en lugar de punteros. Esto asigna el struct en la pila (stack): sin malloc, sin free y sin fugas de memoria.

Ejemplo de una función de fábrica que devuelve por valor:

typedef struct {
    int x;
    int y;
} Point;

Point create_point(int x, int y) {
    Point p;
    p.x = x;
    p.y = y;
    return p;
}

Uso de la función de fábrica:

Point origin = create_point(0, 0);
Point cursor = create_point(100, 50);
printf("Cursor: (%d, %d)\n", cursor.x, cursor.y);

El struct se copia al llamador y se destruye automáticamente cuando sale de su ámbito (scope). Este enfoque funciona mejor para structs pequeños sin miembros asignados dinámicamente.

Pruébalo tú mismo

#include <stdio.h>
#include "temperature.h"

int main() {
    double celsius_input;
    scanf("%lf", &celsius_input);
    
    // TODO: Usa create_temperature para crear una struct Temperature
    
    // TODO: Imprime el valor Celsius usando el formato %.2f
    
    // TODO: Usa temperature_to_fahrenheit para convertir e imprimir el valor Fahrenheit
    
    return 0;
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Object Oriented Programming