Mejor respuesta
Supongo que sabes que cuando ejecutas un programa en C tienes 3 archivos abiertos, dos de ellos se llaman STDOUT y STDERR, los mensajes normales entran en stdout (es decir, cuando llama a printf) y los mensajes de error en stderr (cuando llama, por ejemplo, fprintf (stderr, …), estos dos (archivos abiertos en realidad) están directamente vinculados por su sistema operativo a su terminal, ya sea un terminal Unix o un terminal de Windows. La característica más importante de ellos es que pueden ser redirigidos, por ejemplo en Unix cuando lo hace: ls | grep file.txt el shell redirige stdout en «ls» y ahora el destino para esa salida es STDIN en el proceso «grep», por lo que grep puede buscar patrones en ese flujo, etc. Esto es algo poderoso, muchos filtros Unix (programas en realidad) están construidos de esta manera, lo cual es poderoso.
EDITAR: agregue un ejemplo más significativo Permítanme agregar un uso nuevo y más explícito de la redirección para que pueda comprender la cosa con un ejemplo más significativo, mire este comando:
curl http://ftp.gnu.org/gnu/wget/wget-1.17.1.tar.xz | xzcat – | tar xvf –
Aquí curl comienza a descargar wget del proyecto GNU, mientras que curl está descargando datos que está escribiendo en STDOUT, pero el shell ha redirigido stdout de curl a stdin de xzat, el shell hace el lo mismo, redirige la salida estándar de xzcat a stdin de tar, y tar comienza a descomprimir los datos, ¡increíble!
Respuesta
Primero, un principio general: no importa lo que hagas, malloc()
nunca se invoca automágicamente.
Cuando declaras un struct
, declaras un tipo. Un tipo, por sí mismo, no consume memoria en tiempo de ejecución.
Cuando declaras una variable del tipo struct, se le asigna memoria, pero sin usar malloc()
. Si la variable es local a una función, la memoria para ella generalmente se asigna en la pila. Esto, en parte, es lo que hace posible la recursividad en C: cada vez que llama a la función (incluso si se llama desde dentro de sí misma), el puntero de la pila se ajusta y se reserva nuevo espacio en la pila para la locomotora todas las variables de esa función, y cada vez que se sale de la función, la pila se «desenrolla», con todo ese espacio liberado.
Cuando declaras una variable global, se realiza una asignación estática para ella en el montón cuando se inicia el programa, y la variable permanece disponible durante la ejecución del programa. El tamaño de pila requerido se conoce en tiempo de compilación.
Por el contrario, cuando usa malloc()
, el sistema operativo asigna memoria dinámicamente en tiempo de ejecución al programa y usted es responsable de liberarlo usando free()
, o su programa (especialmente si es un programa que se ejecuta durante mucho tiempo sin reiniciarse, por ejemplo, una aplicación de servicio) sufrirá una pérdida de memoria, que afecta el rendimiento y, en un caso extremo, priva a todo el sistema de recursos. El uso de malloc()
es más apropiado cuando a) la cantidad de memoria requerida es mayor de la que se puede asignar en el montón o la pila, ob) la cantidad de memoria requerida no es conocido de antemano.