I files .c e .exe ovviamente si salvano sul disco rigido. Sulla RAM, e lo dice proprio il nome(Random Access Memory), è la memoria temporanea. Quando il compilatore crea il file .exe, non fa altro che tradurre in linguaggio macchina, una sequenza lunghissima di 0 e 1, le istruzioni del linguaggio di alto livello quale è il C/C++. Quando viene lanciato un programma, sulla RAM avviene una segmentazione della memoria, e al programma viene asseganta una porzione più o meno grande di RAM. All'interno di questa porzione ci sono 5 "blocchi": testo, dati, bss, heap e stack. Il primo si dice segmento del testo, e contiene il programma tradotto in linguaggio macchina, e non può essere assolutamente modificato. Durante l'esecuzione del programma, il registro EIP punta a questo blocco, leggendo passo passo ogni istruzione. Il blocco dati e il bss contengono le variabili statiche e le costanti. Questi possono essere modificati, ma non possono cambiare di dimensione. Heap è un blocco molto importante, è quello dedicato alla allocazione dinamica della memoria(quando usi malloc() ti riservi una porzione di memoria sull'heap, per intenderci..). Ha ovviamente dimensioni variabili anch'esso. Poi c'è lo stack, dove vengono memorizzate le variabili. Questo è molto particolare. Se per esempio hai bisogno di richiamare una funzione che utilizza variabili dichiarate all'interno di esse, quelle si memorizzano nello stack. Lo Stack usa come metodo di allocazione della memoria la struttura FILO(First In, Last Out), vuol dire che l'ultimo blocco di variabili salvato nello stack sarà l'ultimo a poter essere utilizzato. Questa struttura è fondamentale; se infatti ho bisogno di una funzione all'interno del mio programma, lo stack allocherà innanzi tutto un blocco all'interno del quale ci saranno le variabili della funzione main(), poi, al richiamo di ogni funzione, allocherà un blocco con le variabili di quella funzione, così, anche se nelle due funzioni esistono due variabili con lo stesso nome, lo stack potrà lavorare con una di esse all'interno della funzione che è chiamata nel main() usando il blocco di variabili di quella funzione. Quando la funzione termina, lo Stack dealloca il blocco di quella funzione e torna a lavorare col blocco del main(). Quindi il blocco di variabili del main(), che era stato allocato per prima, è diventato utilizzabile per ultimo.
Spero sia stato abbastanza chiaro e spero abbia soddisfatto le tue richieste!