// Tres firmas, tres respuestas a la pregunta: ¿quién libera?
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// Devuelve una cadena nueva con text en mayúsculas, o NULL si no hay memoria.
// Quien llama es owner del resultado, y debe liberarlo con free.
char *upper_copy(const char *text) {
    char *copy = malloc(strlen(text) + 1);
    if (copy == NULL) {
        return NULL;
    }

    size_t i = 0;
    for (; text[i] != '\0'; i++) {
        copy[i] = (char) toupper((unsigned char) text[i]);
    }
    copy[i] = '\0';
    return copy;
}

// Cambia text en su lugar. El owner de text sigue siendo quien llama.
void upper_in_place(char *text) {
    for (size_t i = 0; text[i] != '\0'; i++) {
        text[i] = (char) toupper((unsigned char) text[i]);
    }
}

// Devuelve una de las dos cadenas que recibió. No hay memoria nueva: no se libera.
const char *longer_of(const char *a, const char *b) {
    return strlen(a) >= strlen(b) ? a : b;
}

int main(void) {
    char *upper = upper_copy("paradero");
    if (upper == NULL) {
        return 1;
    }
    printf("%s\n", upper);
    free(upper);

    char word[] = "ruta";
    upper_in_place(word);
    printf("%s\n", word);

    printf("%s\n", longer_of("Lima", "Arequipa"));
    return 0;
}
