View Full Version : [c]il programma ha causato una violazione di accesso(errore di segmentazione)
che vuol dire questo errore?me lo da su una if...
Stai tentando di accedere a una locazione di memoria a cui non hai accesso; controlla con attenzione cosa succede in quell'if.
struct posizione {
int x;
int y;
struct posizione *pun;
};
struct posizione *P;
L=alloca_matrice(N ,M );
....
if(incrocio(P,L))
....
char **alloca_matrice(int all_righe,int all_colonne)
{
char **Labirinto;
int i=0;
Labirinto=(char **)malloc(sizeof(char*)*all_righe);
for(i=0;i<all_righe;i++)
{
Labirinto[i]=(char *)malloc(sizeof(char)*all_colonne);
}
return (Labirinto);
}
int incrocio(struct posizione *p,char **L){
printf("\nINCROCIO");
int i,x,y;
x=p->x;
y=p->y;
// printf("incrocio[%d][%d]",x,y);
i=0;
if((L[x-1][y]==SIMBOLO_VUOTO)||(L[x-1][y]==SIMBOLO_CAMMINO)){i=i+1;printf("incrocio1[%d][%d]",x-1,y);system("PAUSE");}
if((L[x][y-1]==SIMBOLO_VUOTO)||(L[x][y-1]==SIMBOLO_CAMMINO)){i=i+1;printf("incrocio2[%d][%d]",x,y-1);system("PAUSE");}
if((L[x+1][y]==SIMBOLO_VUOTO)||(L[x+1][y]==SIMBOLO_CAMMINO)){i=i+1;printf("incrocio3[%d][%d]",x+1,y);system("PAUSE");}
if((L[x][y+1]==SIMBOLO_VUOTO)||(L[x][y+1]==SIMBOLO_CAMMINO)){i=i+1;printf("incrocio4[%d][%d]",x,y+1);system("PAUSE");}
// printf("i=%d - FINE INCROCIO",i);
system("PAUSE");
return (i>2);
}
il problema mi si presenta sulla prima if e sulla terza.
praticamente creo una matrice dinamica che rappresenta un labirinto,e io devo trovare l'uscita.nelle if controllo le caselle adiacenti a quella iniziale.
wingman87
17-01-2011, 13:17
Per capire cosa c'è che non va serve anche il codice in cui allochi la memoria, la definizione delle strutture dati che utilizzi e le chiamate alla funzione che ti da problemi. Inoltre non farebbe male sapere qual è la logica di fondo di quello che stai facendo oltre che il punto esatto in cui ottieni l'errore.
ho modificato e aggiunto....:D
ora potete massacrarmi :D
wingman87
17-01-2011, 13:50
Dalla descrizione del problema mi viene subito questo dubbio: posto che la cella iniziale sia nell'angolo in alto a sinistra della matrice, non è che tenti di controllare la cella a sinistra e quella in alto (che non esistono)? In generale fai attenzione, nel controllo delle celle adiacenti, quando ti trovi ad un estremo della matrice?
Si ci avevo pensato anche io...pero'... ti faccio un esempio...
l'entrata ha coordinata x=0 e y=8,ma lui l'errore me lo da sulla if che controlla la casella x=1 e y=8....
che ne pensi?
banryu79
17-01-2011, 15:18
Controlla meglio quello che ti ha detto wingman87.
Ad esempio, prova a pensare a cosa succede quando viene eseguito questo pezzo di codice, quando x vale 0:
if((L[x-1][y]==SIMBOLO_VUOTO)||(L[x-1][y]==SIMBOLO_CAMMINO)){i=i+1;printf("incrocio1[%d][%d]",x-1,y);system("PAUSE");}
if((L[x][y-1]==SIMBOLO_VUOTO)||(L[x][y-1]==SIMBOLO_CAMMINO)){i=i+1;printf("incrocio2[%d][%d]",x,y-1);system("PAUSE");}
if((L[x+1][y]==SIMBOLO_VUOTO)||(L[x+1][y]==SIMBOLO_CAMMINO)){i=i+1;printf("incrocio3[%d][%d]",x+1,y);system("PAUSE");}
if((L[x][y+1]==SIMBOLO_VUOTO)||(L[x][y+1]==SIMBOLO_CAMMINO)){i=i+1;printf("incrocio4[%d][%d]",x,y+1);system("PAUSE");}
Chiaramente può succedere un casino, perchè vai a leggere in una locazione di memoria non inizializzata. Da cui seguono effetti vari a (dis)piacere...
struct posizione *crea_entrata_labirinto(char **matrice,int eu_lrig,int eu_lcol)
{
struct posizione *coordinate_entrata, *punt;
int i,j,entrata=0;
srand(time(NULL));
coordinate_entrata = (struct posizione *)malloc(sizeof(struct posizione));
//printf("Inserisci x: ");
// scanf("%d", & ex->x);
//printf("\nInserisci y: ");
//scanf("%d", & ex->y);
while(entrata==0)
{
i=rand()%eu_lrig;
//printf("i=%d\n",i);
//getch();
if((i==0)||(i==eu_lrig-COSTANTE1))//serve per gli spigoli
{
j=rand()%eu_lcol;
//printf("j=%d",j);
if ((j==0)||(j==eu_lcol-COSTANTE1))//serve per gli spigoli
{
}
else
{coordinate_entrata->x=i;
coordinate_entrata->y=j;
printf("E[%d][%d]",i,j);
matrice[i][j]=SIMBOLO_ENTRATA;
entrata=1;
}
}
else
{
j=rand()%eu_lcol;
if ((j==0)||(j==eu_lcol-1))//serve per gli spigoli
{
// printf("giovanni\n");
coordinate_entrata->x=i;
coordinate_entrata->y=j;
matrice[i][j]=SIMBOLO_ENTRATA;
entrata=1;
printf("E[%d][%d]",i,j);
}
else
{
}
}
}
coordinate_entrata->pun = NULL;
return(coordinate_entrata);
}
questa funzione impedisce che l'entrata sia ai vertici,quindi pensate che debba fare una cosa del genere anche per quelle if....giusto?
cmq perche' se ho x=0 e y=9 per esempio non mi da quell'errore?
banryu79
18-01-2011, 09:29
cmq perche' se ho x=0 e y=9 per esempio non mi da quell'errore?
E' da più di 4 anni che non tocco codice C, quindi chiedo venia se dico inesattezze, eventualmente qualcun'altro preciserà le cose.
Da quello che ricordo, usare un numero negativo come indice per deferenziare una locazione di un array, di per se non si può.
Però secondo le regole dell'aritmetica dei puntatori a[i] viene trattato esattamente come *(a+i), dove a è un puntatore.
Questo per il discorso sull'aritmentica dei puntatori.
Nel tuo codice "L" non è un array in senso stretto, ma un puntatore, quindi L[x+1][y], con x che vale 0 e y che vale 9 equivale a *(L+0+1+9).
Con x che vale 1 e y che vale 8 viene fuori *(L+1+1+8), e così via.
Probabilmente prima o poi "sfori" e vai a puntare fuori dalla memoria che hai allocato per l'array bidimensionale...
grazie banryu79,ma come lo risolvo il problema?
wingman87
18-01-2011, 14:30
E' da più di 4 anni che non tocco codice C, quindi chiedo venia se dico inesattezze, eventualmente qualcun'altro preciserà le cose.
Da quello che ricordo, usare un numero negativo come indice per deferenziare una locazione di un array, di per se non si può.
Però secondo le regole dell'aritmetica dei puntatori a[i] viene trattato esattamente come *(a+i), dove a è un puntatore.
Questo per il discorso sull'aritmentica dei puntatori.
Nel tuo codice "L" non è un array in senso stretto, ma un puntatore, quindi L[x+1][y], con x che vale 0 e y che vale 9 equivale a *(L+0+1+9).
Con x che vale 1 e y che vale 8 viene fuori *(L+1+1+8), e così via.
Probabilmente prima o poi "sfori" e vai a puntare fuori dalla memoria che hai allocato per l'array bidimensionale...
Non sono sicurissimo neanche io ma credo che non sia proprio così. In particolare L è un doppio puntatore, quindi L[x+1] equivale a *(L+x+1) mentre L[x+1][y] equivale a *(*(L+x+1)+y). Il motivo per cui quando sfori dalla zona allocata per la matrice a volte non ti da errore è che molto probabilmente stai sforando in una zona di memoria che è stata comunque allocata da te e a cui quindi hai accesso.
Faccio un esempio banale: prima allochi un array di 10 interi "arr" e poi un intero "a". Se accedi ad arr[10], se le aree allocate sono adiacenti, sfori dall'array ma finisci per puntare ad a e non ottieni un errore di accesso.
Per risolvere il problema: quando stai per controllare una cella adiacente controlla prima che questa esista.
ok credo di aver capito...esempio di soluzione:
controllo che x-1 , x+1 e y-1,y+1 siano sempre maggiori o uguali a 0 e minori o uguali al numero massimo di celle allocate...
giusto?
wingman87,ti ho anche mandato un pm :D
wingman87
18-01-2011, 14:42
ok credo di aver capito...esempio di soluzione:
controllo che x-1 , x+1 e y-1,y+1 siano sempre maggiori o uguali a 0 e minori o uguali al numero massimo di celle allocate...
giusto?
Giusto
wingman87,ti ho anche mandato un pm :D
Sì ma non ho molta voglia di seguire anche l'altra discussione in questo momento...
ok grazie wingman87...se ti viene voglia butta un occhio :D birra pagata sicuro :D
banryu79
18-01-2011, 14:50
Non sono sicurissimo neanche io ma credo che non sia proprio così. In particolare L è un doppio puntatore, quindi L[x+1] equivale a *(L+x+1) mentre L[x+1][y] equivale a *(*(L+x+1)+y).
Già, hai ragione.
In ogni caso anche io consiglio vivamente a mic85rm di controllare la validità degli indici prima di usarli per accedere alla matrice.
grazie banryu...
faccio una bella if con i controlli che ho scritto poco sopra...
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.