Originariamente inviato da Laikius91 ... se una funzione mi deve ritornare una stringa creata all'interno della funzione, questa non può essere stata allocata normalmente, con
char stringa [10];
ma occorre averla allocata ad esempio con:
char* stringa;
stringa = (char*) malloc (sizeof (char) * 10);
A livello pratico/teorico come si spiega questa cosa?
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.