Newsgroup: it.comp.lang.c
Titolo: Dubbio su function

Salve a tutti, ho un dubbio sulla funzione che ho scritto io,
funzione:
void *takestr(char *str)
{
   char c;
   int i=0;
    do
    {
     c=getchar(); //prendo il carattere
     str=(char *)realloc(str,i+sizeof(char)); //alloco una posizione di 
piu' nella stringa
     str[i]=c; //aggiungo il carattere alla stringa
     i=i+1;
    }while(c != '\n');  //prendo un carattere alla volta finche non 
viene l'invio
return str; //ritorno un puntatore alla prima posizione della stringa
}
Il mio dubbio consiste nel fatto che se nel main faccio cosi':
main()
{
char *s;
s=takestr(s);
}
la stringa s è quello che volevo ottenere, ma non dovrebbe funzionare 
anche richimanado semplicemente la funzione con "takestr(s);" ?

 anche richimanado semplicemente la funzione con "takestr(s);" ?
quello che vuoi tu lo ottieni passando il puntatore al puntatore s, ovvero
con takestr(&s) (e gestendo di conseguenza il doppio puntatore dentro
la funzione takestr( char ** str)).
provo (e sottolineo provo) a spiegare il perché non funziona:
quello che fai tu è dichiarare un puntatore s nel main.
char * s; // il suo indirizzo è $A e in questo momento punta a una zona
non definita che chiameremo $B
quando chiami takestr(s), nella funzione takestr ti ritrovi una variabile
puntatore 'str' che punta a $B e ha indirizzo $C.
quando chiami realloc, l'indirizzo della zona di memoria allocata ($D) è
copiato sulla zona di memoria di indirizzo $C, ovvero 'str'. Infine, $D
viene ritornato..
Come vedi ogni traccia di 'char * s' si perde alla prima chiamata di
realloc. In particolare, l'indirizzo di s ($A) non viene mai passato a
takestr() che quindi non potra mai copiarci sopra qualcosa, e l'indirizzo
a cui puntava ($B) viene sovrascritto dalla prima assegnazione di str.
Chiaro no ? :P
Ciao
Matic`

 anche richimanado semplicemente la funzione con "takestr(s);" ?
in questo caso otterrai un bel crash in quanto dai come input un 
puntatore non inizializzato (a che blocco di memoria sta puntando? dove 
la funzione takestr va a scrivere?), comunque se s fosse correttamente 
inizializzato (del tipo char *s = malloc(1024);) funzionerebbe anche in 
quel modo..
saluti
antonio

Grazie mille matic, sei stato preciso e conciso,
non mi sapresti mica dire perchè la mia funzione non prende piu' di 8 
caratteri? :(



Come ha giustamente fatto notare Antonio Mazzeo e non mi ero accorto, alla
prima chiamata di realloc, str DEVE puntare o a NULL o a una zona già
mallocata altrimenti quello che ottieni è tutto un comportamento
indefinito (probabilmente ti crasha).
Forse è dovuto a questa la tua limitazione ? Per il resto, nel codice,
non c'è un limite di 8 caratteri.. non saprei

      str=(char *)realloc(str,i+sizeof(char)); //alloco una posizione di 
Questo uso di realloc() è sbagliato.
1. il cast in C non è necessario;
2. sizeof(char) = 1 sempre;
3. se realloc() fallisce (improbabile ma possibile), si ottiene un memory
leak.  Bisogna sempre scrivere qualcosa del tipo:
char *p = realloc(str, i);
if (p)
{
   str = p;
}
-- 
questo articolo e` stato inviato via web dal servizio gratuito 
http://www.newsland.it/news
 segnala gli abusi ad 
ab...@newsland.it