Hay dos lugares donde las variables se pueden guardar en la memoria. Cuando creas una variable como esta:
int a;
char c;
char d[16];
Las variables se crean en la " pila ". Las variables de pila se liberan automáticamente cuando salen del alcance (es decir, cuando el código ya no puede alcanzarlas). Es posible que las escuche llamar variables "automáticas", pero eso ha pasado de moda.
Muchos ejemplos para principiantes usarán solo variables de pila.
La pila es buena porque es automática, pero también tiene dos inconvenientes: (1) El compilador necesita saber de antemano qué tan grandes son las variables y (b) el espacio de la pila es algo limitado. Por ejemplo: en Windows, en la configuración predeterminada del vinculador de Microsoft, la pila se establece en 1 MB y no todo está disponible para sus variables.
Si no sabe en el momento de la compilación qué tan grande es su matriz, o si necesita una matriz o estructura grande, necesita el "plan B".
El plan B se llama " montón ". Por lo general, puede crear variables tan grandes como le permita el sistema operativo, pero debe hacerlo usted mismo. Publicaciones anteriores le mostraron una forma en que puede hacerlo, aunque hay otras formas:
int size;
// ...
// Set size to some value, based on information available at run-time. Then:
// ...
char *p = (char *)malloc(size);
(Tenga en cuenta que las variables en el montón no se manipulan directamente, sino mediante punteros)
Una vez que crea una variable de montón, el problema es que el compilador no puede saber cuándo ha terminado con ella, por lo que pierde la liberación automática. Ahí es donde entra la "liberación manual" a la que se refería. Su código ahora es responsable de decidir cuándo la variable ya no es necesaria y liberarla para que la memoria se pueda utilizar para otros fines. Para el caso anterior, con:
free(p);
Lo que hace que esta segunda opción sea un "negocio desagradable" es que no siempre es fácil saber cuándo ya no se necesita la variable. Olvidar liberar una variable cuando no la necesita hará que su programa consuma más memoria de la que necesita. Esta situación se denomina "fuga". La memoria "filtrada" no se puede utilizar para nada hasta que el programa finalice y el sistema operativo recupere todos sus recursos. Son posibles problemas aún más desagradables si libera una variable de montón por error antes que haya terminado con ella.
En C y C ++, usted es responsable de limpiar sus variables de montón como se muestra arriba. Sin embargo, hay lenguajes y entornos como Java y lenguajes .NET como C # que utilizan un enfoque diferente, donde el montón se limpia por sí solo. Este segundo método, llamado "recolección de basura", es mucho más fácil para el desarrollador, pero paga una penalización en gastos generales y rendimiento. Es un equilibrio.
(He pasado por alto muchos detalles para dar una respuesta más simple, pero con suerte más nivelada)