PDA

Visualizza la versione completa : [C] PROBLEMA - realloc()


Danj97
08-12-2013, 22:17
Buonasera, ho riscontrato un problema con il seguente codice:


/* Prendere in input vettore di 27 numeri e dare come risultato 1 se la
* sequenza di numeri è perfetta, 0 se non lo è */

#include <stdio.h>
#include <stdlib.h>

int isPerfect (int *seq,int isperfect) {
int i=0;
for (i=0;i<(sizeof(seq)/sizeof(int));i++) {
i++;

if (seq[i]==seq[seq[i]+2]) isperfect=1;
else isperfect=0;
}
return isperfect;
}


int main()
{
int i=0,*seq=NULL,n,isperfect=0;
printf("Inserisci 0 per terminare la sequenza\n");
do {
seq=(int *)realloc(seq,((i+1)*sizeof(int)));
//Acquisisco
printf("\nInserisci il %d numero: ",i+1);
scanf("%d",&n);

//Inserisco valore nell'array
i++;
seq[i]=n;
} while(n!=0);


//Chiamo la funzione isPerfect
isPerfect(seq,isperfect);

if (isperfect==1) printf("La sequenza di numeri è perfetta");
else printf("La sequenza di numeri non è perfetta");
free(seq);
return 0;
}

Praticamente la terza volta che immetto il numero (nel ciclo do-while del main) mi dice "realloc(): invalid next size: indirizzo_esadecimale".
Tralasciando la correttezza del'algoritmo in sé vorrei sapere il motivo per cui mi da errore sulla realloc. Ho provato ad usare valgrind (opero in ambiente Linux, su Ubuntu) per vedere se centrava il memory leak, seppur ero certo del fatto che non potesse essere un problema del genere, ed infatti non è quello il problema. Grazie in anticipo :D

Scara95
08-12-2013, 22:34
Gli array in C sono 0 based quindi tu inserisci l'elemento sempre fuori dai confini dell'array. Devi spostare i++ dopo l'assegnamento.
isperfect nella funzione isPerfect è una variabile locale, perciò non verrà modificato nel main (dove rimarrà sempre 0)
Devi rivedere l'algoritmo nella funzione isPerfect per 2 motivi



Gli array sono 0 based
devi controllare di restare sempre dentro i confini dell'array.

Danj97
08-12-2013, 22:40
Ma se io punto all'indirizzo di memoria di isperfect del main non dovrebbe cambiarmi il contenuto di quell'indirizzo (e quindi l'isperfect del main)?
Comunque sapevo dello 0 based, non avevo proprio fatto caso a quell'errore! :) Per il 3° punto lo so! Esco dall'array in quanto eseguo il ciclo più volte di quante dovrei, ma dovevo finire infatti l'algoritmo e volevo solamente capire l'errore sulla realloc. Il 2° punto non mi è molto chiaro,se è possibile potresti espormelo meglio?

Danj97
08-12-2013, 22:48
Ah no, ho modificato appunto il codice in questo modo! Adesso funziona.



/* Prendere in input vettore di 27 numeri e dare come risultato 1 se la
* sequenza di numeri è perfetta, 0 se non lo è */

#include <stdio.h>
#include <stdlib.h>

int isPerfect (int *seq,int *isperfect) {
int i=0;
for (i=0;i<(sizeof(seq)/sizeof(int));i++) {
i++;

if (seq[i]==seq[seq[i]+2]) *isperfect=1;
else *isperfect=0;
}
return (int) isperfect;
}


int main()
{
int i=0,n,isperfect=0,*seq=NULL;
printf("Inserisci 0 per terminare la sequenza\n");
do {
seq=(int *)realloc(seq,((i+1)*sizeof(int)));
//Acquisisco
printf("\nInserisci il %d numero: ",i+1);
scanf("%d",&n);

//Inserisco valore nell'array
seq[i]=n;
i++;
} while(n!=0);


//Chiamo la funzione isPerfect
isPerfect(seq,&isperfect);

if (isperfect==1) printf("La sequenza di numeri è perfetta");
else printf("La sequenza di numeri non è perfetta");
free(seq);
return 0;
}

Scara95
08-12-2013, 23:01
Dovresti riorganizzare il codice...
Ci sono altri problemi: ad esempio lo 0 finale è un elemento della tua sequenza, non ha senso che il cast nel return, sarebbe meglio passare le dimensioni esplicitamente, ...

Riorganizziamo un po' le cose:
/* Prendere in input vettore di 27 numeri e dare come risultato 1 se la * sequenza di numeri è perfetta, 0 se non lo è */


#include <stdio.h>
#include <stdlib.h>


int isPerfect (int *seq, int size) {
int isperfect = 0, i;
for(i = 0; i < size; i++)
/*...*/;
return isperfect;
}




int main()
{
int i=0,*seq=NULL,n;
printf("Inserisci 0 per terminare la sequenza\n");
while(1) {
//Acquisisco
printf("\nInserisci il %d numero: ",i+1);
scanf("%d",&n);
if(n==0)
break;
//Inserisco valore nell'array
seq=(int *)realloc(seq,(i+1)*sizeof(int));
seq[i]=n;
i++;
}

if (isPerfect(seq, i)==1)
printf("La sequenza di numeri è perfetta");
else
printf("La sequenza di numeri non è perfetta");
free(seq);
return 0;
}

Danj97
08-12-2013, 23:06
E' vero, hai perfettamente ragione. Non avevo pensato che lo 0 lo prende come elemento nella sequenza! Ma nel ciclo for della funzione non faccio prima a scrivere sizeof(seq)/sizeof(int) anziché i<size, passando quindi un argomento in più (e quindi dichiarando una variabile in più)?

Scara95
08-12-2013, 23:12
OMG quello era solo un commento segna posto che voleva dire "completa tu".
La prima cosa da considerare è la chiarezza.

Danj97
08-12-2013, 23:17
Ok,grazie mille per la tua disponibilità! Mi hai chiarito un po' di cose :)

Scara95
09-12-2013, 07:24
Ok,grazie mille per la tua disponibilità! Mi hai chiarito un po' di cose :)
Prego, ma a mio parere dovresti rivedere un po' di nozioni base...
Buona fortuna :ciauz:

Loading