Pagina 1 di 1
Puntatori e costanti
Inviato: mer 23 gen 2008, 21:07
da afterjames
Salve a tutti, ho un dubbio amletico sui puntatori in C.Ho sempre saputo che un buffer si può dichiarare indifferentemente come:
oppure come un array :
essendo un array equivalente ad un puntatore costante a dati variabili, cioè in cui non è possibile cambiare l'indirizzo a cui punta ma soltanto i valori "puntati".
Era tutto abbastanza chiaro, finchè un giorno non provai a fare :
Codice: Seleziona tutto
char *const s="bla bla";
char * ptr;
ptr = strtok(s," ");
Ottenendo un errore di segmentazione..Cosa che non accade se invece faccio:
Codice: Seleziona tutto
char s[]="bla bla";
char * ptr;
ptr = strtok(s," ");
Che differenza c'è tra la versione con il puntatore e quella con il vettore?
Re: Puntatori e costanti
Inviato: mer 23 gen 2008, 23:11
da Calzo
Dovrebbe essere legato al fatto che definendo una stringa tra *s="" (o const *s="") viene allocata una zona di memoria read-only.
Infatti se fai:
Codice: Seleziona tutto
char s[]="abc";
char t[]="123";
char *x="def";
char *y="456";
void main() {
printf("%X\n%X\n%X\n%X\n",s,t,x,y);
}
vedrai che la memoria non è contigua. A me x esempio torna questo:
Inoltre la funzione che hai usato tu modifica direttamente *s. Ti dovrebbe dare un seg fault anche se fai s[1]='x'.
Re: Puntatori e costanti
Inviato: mer 23 gen 2008, 23:13
da phobos3576
Se apri un terminale e dai il comando
man strtok puoi notare che:
Codice: Seleziona tutto
Avoid using these functions. If you do use them, note that:
These functions modify their first argument.
These functions cannot be used on constant strings.
The identity of the delimiting character is lost.
The strtok() function uses a static buffer while parsing, so it's
not thread safe. Use strtok_r() if this matters to you.
Quindi,
strtok modifica il suo primo argomento!
La stringa
"bla bla", creata come hai fatto tu, è una
stringa costante; il compilatore la sistema nel blocco dati globale del programma.
Come risulta dallo standard ANSI C: "
se si tenta di modificare una stringa costante, il risultato è indefinito".
E' la stessa situazione che si verifica quando si scrive:
La stringa
"ciao", non avendo un nome, non risulta accessibile in scrittura.
Il modo corretto di procedere consiste nello scrivere, ad esempio:
Re: Puntatori e costanti
Inviato: gio 24 gen 2008, 10:17
da afterjames
Allora..Due cose:La stringa così dichiarata:
Non è costante, in quanto è il puntatore ad essere costante(e non i valori puntati!).Questa è una stringa costante:
Ora, utilizzando la strtok, anche con una semplice:
Codice: Seleziona tutto
char *str="bla blabla";
char *ptr;
ptr=strtok(ptr," ");
Ottengo ugualmente un errore di segmentazione..Ma dovrei aver capito perchè!In realtà c'è differenza tra il dichiarare una stringa come un buffer e come un puntatore.Su un manuale ho letto che:
"Alcuni compilatori potrebbero sistemare una variabile di tipo char* che sia stata inizializzata con una stringa letterale,
in una locazione di memoria in cui non possa essere modificata
"
Dovrebbe essere per questo il motivo..Grazie a tutti
Re: Puntatori e costanti
Inviato: gio 24 gen 2008, 10:58
da targzeta
afterjames ha scritto:Allora..Due cose:La stringa così dichiarata:
Non è costante, in quanto è il puntatore ad essere costante(e non i valori puntati!).
Errore, questa è una dichiarazione di puntatore costante a stringa che viene memorizzata in un area di memoria in read only, quindi, se vuoi è costante.
Con questa dichiarazione, anche fare
non è valido.
Per usare una funzione che modifica l'area di memoria, devi o usare l'allocazione dinamica, oppure fare una dichiarazione del tipo:
in questo caso, str punterà ad una locazione di memoria che verrà allocata in fase di esecuzione e che conterrà la stringa "blablabla".
Nota che in questo caso, str è ancora un puntatore costante, nel senso che non è valido fare:
ma in questo caso è possibile modificare il contenuto di memoria a cui esso punta.
La tua dichiarazione invece è molto più restrittiva, il tuo puntatore str non può puntare a nient'altro che alla stringa "blablabla", e, l'area di memoria che contiene la stringa "blablabla" non può essere modificato. La tua dichiarazione è simile a questa:
Spina
Re: Puntatori e costanti
Inviato: gio 24 gen 2008, 21:02
da robbybby
Io evito la strtok come la peste! Mi ha dato un sacco di problemi appena un programma in cui la usava e' passato da single thread a multi thread.
Preferisco fare il parsing usando la strchr(). Alla fine e' comoda uguale, ed esente da problemi in programmi multithreding (semplicemente perche' non c'e' il buffer statico, e i puntatori ai vari token me li tengo io su variabili automatiche, quindi sul mio stack).