PDA

Visualizza la versione completa : [C]ritornato char* da funzione in maniera assurda


shinichi
11-12-2008, 22:22
Stavo scrivendo una funzione per convertire un numero decimale in binario, che ritorna come un puntatore di caratteri

due errori:il primo è che mi ero dimenticato di allocare la memoria per il puntatore,la seconda è che ho sbagliato l'inizializzazione di un array... il comilatore compila senza fiatare...

il risultato è che la funzione ritorna la stringa giusta senza uso di malloc O_o



char* dectobin(int decimale);
char* dectobin(int decimale)
{
int I,contatore;
char* binario;
char arraybin[I]; //-----------??????????????
//---------------------------il seguente blocco calcola la lunghezza dell'equivalente binario
I=0;
contatore=decimale;
while(contatore != 0)
{
contatore/=2;
I++;
}
arraybin[I]='\0'; //-----------preparo l'array per diventare pseudo-stringa
//-------------------------- il seguente blocco riempie l'array
for(--I;I>0 || I==0;I--)
{
decimale % 2 == 0 ? arraybin[I]='0' : arraybin[I]='1';
decimale /= 2;
}
//---------------------------dopo di che assegno l'indirizzo e ritorno il puntatore
binario=&arraybin[0];
return binario;
}



il vettore di caratteri relativo al puntatore ritornato lo ho stampato nella main con printf senza problemi,da notare che se si sposta la dichiarazione di arraybin dopo il ciclo while,il posto corretto, le celle all'indirizzo del puntatore si svuotano nel passaggio alla main come norma.

qualcuno è cosi gentile da svelarmi l'arcano ? XD

MItaly
11-12-2008, 23:04
Per quanto riguarda l'array si tratta probabilmente di estensioni non standard del compilatore gcc, per cui è possibile dichiarare un array di dimensioni note a runtime come variabile automatica; probabilmente I, non venendo inizializzato ad un valore particolare, risulta pari a un qualche valore casuale tale che l'array arraybin risulti comunque sufficientemente grande per contenere la stringa da restituire.

shinichi
12-12-2008, 14:36
per quanto riguarda la I sono d'accordo, pero mi lascia perplesso il discorso sulla visibilità...
dal momento che se inizializzo correttamente l'array la stringa non ritorna ciò mi fa pensare che l'eccezione non sia il compilatore ma compilato

no?

oregon
12-12-2008, 15:55
Originariamente inviato da shinichi
per quanto riguarda la I sono d'accordo, pero mi lascia perplesso il discorso sulla visibilità...
dal momento che se inizializzo correttamente l'array la stringa non ritorna ciò mi fa pensare che l'eccezione non sia il compilatore ma compilato

no?

Non ho capito tanto il tuo discorso ma, comunque, non puoi restituire il puntatore ad un array locale alla funzione peeche' all'uscita dalla stessa lo spazio dell'array e' invalidato (anche se continua ad esistere finche' non riutilizzato e sovrascritto ...)

shinichi
12-12-2008, 18:56
uff pero se leggi bene cio che ho scritto il punto è proprio questo

se l'array lo inizializzo bene il puntatore a stringa da ritornare non punta a niente appena esce dalla funzione

mentre se inizializzo l'array con I soltanto dichiarata l'array in resta memoria dopo l'uscita dalla funzione... e cio è provato dalla printf che ho messo nel main nei due casi che ho testato e citato

oregon
12-12-2008, 18:59
Originariamente inviato da shinichi
uff pero se leggi bene ...

Calma ... ho letto bene ...

Ma se lo facessi tu, leggeresti che ti ho detto che e' sbagliato usare un array allocato internamente ad una funzione e restituirne il puntatore ... in ogni caso ...

Il comportamento di un programma che fa questo tipo di operazione, risulta indefinito ...

Fai cosi' ...



char *dectobin(int decimale)
{
int contatore=decimale, i=0;

while(contatore)
{
contatore/=2;
i++;
}

char *arraybin = (char *)calloc(i+1, sizeof(char));

for(--i; i>0 || i==0; i--, decimale /= 2)
arraybin[i] = (decimale % 2 == 0) ? '0' : '1';

return arraybin;
}

int main()
{
char *p = dectobin(256);

printf("%s\n", p);

free(p);

return 0;
}

shinichi
13-12-2008, 15:14
capito capito

comunque prima di leggere questo messaggio avevo gia finito il codice in maniera corretta e funzionante utlizzando il puntatore in forma array.



char* dectobin(int decimale);
char* dectobin(int decimale)
{
int I,K,contatore;
I=0;
K=0;
contatore=decimale;
while(contatore != 0)
{
contatore/=2;
I++;
}
if(decimale<0)
{
I++;
K++;
}
char* binario ;
binario = (char*)malloc(I+1);
binario[I]='\0';
if(decimale<0)binario[0]='-';
for(--I;I>0 || I==K;I--)
{
decimale % 2 == 0 ? binario[I]='0' : binario[I]='1';
decimale /= 2;
}
return binario;
}



(questo lavora anche con i numeri negativi)

ora che ho letto la tua proposta moltiplichero lo scalare nelle parentesi della malloc e semplifichero la scrittura del ciclo for

grazie ancora

shinichi

Loading