PDA

View Full Version : Il ciclo di vita delle stringhe (*char) in C


Dark Phoenix
06-06-2007, 14:09
Ho un dubbio che mi perseguita sul ciclo di vita delle stringhe in C.

Se io dichiaro a livello di procedura una stringa senza effettuare una malloc, cioè in questi modi:

1) char c[256];

2) char *c;
c = "Sono una stringa";

le stringhe continueranno in entrambi i casi ad esistere alla fine dell'esecuzione della procedura? o no?
In altre parole vengono allocate sullo stack? (Il puntatore di sicuro si ma il resto?)
In poche parole posso evitare di fare un'altra malloc :cry:

ilsensine
06-06-2007, 14:36
le stringhe continueranno in entrambi i casi ad esistere alla fine dell'esecuzione della procedura? o no?
La prima no, la seconda sì.

andbin
06-06-2007, 14:38
In altre parole vengono allocate sullo stack? (Il puntatore di sicuro si ma il resto?)
In poche parole posso evitare di fare un'altra malloc :cry:Le variabili locali ad una funzione (non marcate 'static', precisiamo) sono allocate sullo stack e sono dette "automatiche" perché la loro vita finisce quando la funzione termina.

È chiaro che fare char c[256] e fare char *p="...." sono cose un po' diverse.

Con char c[256] si alloca sullo stack un array di 256 char. Terminata la funzione, l'array sparisce.

Con char *c = "blabla" si alloca sullo stack solamente un puntatore, inizializzato subito in modo da puntare ad una stringa "literal". Quest'ultima è allocata in modo fisso e permanente in un "costant string pool", una zona di memoria dove risiedono le stringhe costanti.
Terminata la funzione, solo la variabile puntatore sparisce, non la stringa literal.

Mentre il contenuto dell'array di char è alterabile dalla funzione, il contenuto della stringa literal non è alterabile (a seconda dell'ambiente).

ilsensine
06-06-2007, 14:46
È chiaro che fare char c[256] e fare char *p="...." sono cose un po' diverse.
Inoltre la prima forma definisce un puntatore che non può essere modificato, al contrario della seconda forma.

Dark Phoenix
06-06-2007, 14:58
Permettetemi l'espressione: "Wow quanto spignete"

quindi se in una procedura ho come argomento char *c
non posso sapere a priori se quella stringa punta a un qualcosa allocato sullo stack di una qualche altra procedura oppure no...

che pezza :muro:

ilsensine
06-06-2007, 15:00
quindi se in una procedura ho come argomento char *c
non posso sapere a priori se quella stringa punta a un qualcosa allocato sullo stack di una qualche altra procedura oppure no...
Non vedo perché ti dovrebbe interessare...

Dark Phoenix
06-06-2007, 15:30
Perché se io mi "appendo" semplicemente alla stringa, quindi senza effettuare una copia, e la procedura chiamante termina trascinandosi lo stack può rimanere appesso un puntatore su un qualcosa che viene deallocato... e quindi può sorgere un problema di natura variabile...

Insomma non posso definire con rigidità(da compilatore) il contratto di un operazione che non fa altro che appendere (nel senso stendino :) ) la stringa al posto giusto.
In poche parole sono costretto a distinguere i due casi con due operazioni differenti.

ilsensine
06-06-2007, 15:45
Perché se io mi "appendo" semplicemente alla stringa, quindi senza effettuare una copia, e la procedura chiamante termina trascinandosi lo stack può rimanere appesso un puntatore su un qualcosa che viene deallocato... e quindi può sorgere un problema di natura variabile...
Il tuo problema è a monte. Se ti serve il contenuto di quella stringa senza poter fare assunzioni da dove proviene, anche _dopo_ che la tua procedura termina, ad es. perché la devi "appendere" da qualche parte e lì deve rimanere, __devi__ farne una tua copia personale. Ok la memoria può provenire o meno dallo stack; ma se non proviene dallo stack ed è stata ottenuta con malloc, e successivamente viene liberata con free? Se viene sovrascritta da altre parti del programma?

Dark Phoenix
06-06-2007, 15:50
Il tuo problema è a monte. Se ti serve il contenuto di quella stringa senza poter fare assunzioni da dove proviene, anche _dopo_ che la tua procedura termina, ad es. perché la devi "appendere" da qualche parte e lì deve rimanere, __devi__ farne una tua copia personale. Ok la memoria può provenire o meno dallo stack; ma se non proviene dallo stack ed è stata ottenuta con malloc, e successivamente viene liberata con free? Se viene sovrascritta da altre parti del programma?

E qui non posso far altro che inchinarmi...
Non hai ragione ma di più...