Originariamente inviato da Paulin
A leggere così sembra che la risposta che cerchi non sia tanto come funziona l'heap, ma il perché una variabile debba essere allocata sull'heap.

In realtà la stringa char* stringa;
allocata come stringa = (char*) malloc (sizeof (char) * 10);
potrebbe benissimo essere allocata come char stringa [10];
Nel primo caso andrà a finire nel Private Heap del processo, nel secondo caso andrà a finire comunemente nel data segment, ma nulla cambia (a parte il fatto che l'accesso all'heap è leggermente più lento) dal momento che tu hai specificato il numero di caratteri a compile time e verrà comunque riservando uno spazio di 10 bytes.

Il motivo per cui si ricorre all'allocazione sull'heap è che l'heap è "growable", ovvero può accrescere a seconda della necessità del processo. Così una allocazione del tipo:

stringa = (char*) malloc (sizeof (char) * numOfChars);

potrà richiedere al sistema uno spazio di memoria extra (rispetto ai segmenti di dimensione fissa dell'immaggine dell'applicativo in memoria) che sarà determinato soltanto quando l'applicativo sarà in esecuzione, ovvero quando la variabile numOfChars riceverà il suo valore. Per questo motivo la memoria allocata dinamicamente non è detto che sia sistemata su uno spazio contiguo, è verosimilmente più facile che sia distribuita in diversi frammenti. Quando il processo avrà liberato la memoria richiesta con free(stringa) questa quantità di memoria ritornerà al sistema. Per questo è importante ricordarsi di liberare prima di perdere il puntatore.
Tutto chiaro grazie mille davvero!
Quello che comunque non avevo subito capito era perchè una stringa allocata normalmente avevo tempo di vita pari a quello della sua funzione e quindi non poteva essere ritornata (poichè variabile locale!), mentre una stringa allocata "pseudo-dinamicamente" (passami il termine) aveva tempo di vita indipendente dalla funzione che la creava e pertanto poteva essere il valore di ritorno della funzione stessa.
Ora ho chiarito davvero tutto, grazie ancora!