Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - segmentation fault
Forum - C/C++ - segmentation fault

Avatar
orion3 (Normal User)
Rookie


Messaggi: 28
Iscritto: 16/04/2011

Segnala al moderatore
Postato alle 17:55
Venerdì, 02/11/2012
Ciao a tutti, stavo facendo un esercizio per la scuola e mi sono imbattuto nell'errore di segmentation fault. Non riesco a capire come mai mi dia quell'errore, comunque il codice e' questo:
Codice sorgente - presumibilmente C++

  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4.  
  5.  
  6.  
  7. int main()
  8. {
  9.     int rows,cols,dir=1,n_cella=1,r=rows,c=0,celle_tot;
  10.     cout<<"Inserisci il numero di righe: ";
  11.     cin>>rows;
  12.     cout<<"Inserisci il numero di colonne: ";
  13.     cin>>cols;
  14.  
  15.  
  16.     vector <vector<int> > matrice (rows, vector<int>(cols,0));
  17.     celle_tot=rows*cols;
  18.     while (n_cella<celle_tot){
  19.         while(dir==1){
  20.             if(matrice[r][c]== 0 && r>0){
  21.                 matrice[r][c]=n_cella;
  22.                 n_cella+=1;
  23.                 r-=1;
  24.             }
  25.             else{
  26.                 dir=2;
  27.                 r+=1;
  28.                 n_cella-=1;
  29.             }
  30.         }
  31.         while(dir==2){
  32.             if(matrice[r][c]== 0 && c<cols){
  33.                 matrice[r][c]=n_cella;
  34.                 n_cella+=1;
  35.                 c+=1;
  36.             }
  37.             else{
  38.                 dir=3;
  39.                 c-=1;
  40.                 n_cella-=1;
  41.             }
  42.         }
  43.         while(dir==3){
  44.             if(matrice[r][c]== 0 && r<rows){
  45.                 matrice[r][c]=n_cella;
  46.                 n_cella+=1;
  47.                 r+=1;
  48.             }
  49.             else{
  50.                 dir=4;
  51.                 r-=1;
  52.                 n_cella-=1;
  53.             }
  54.         }
  55.         while(dir==4){
  56.             if(matrice[r][c]== 0 && c>0){
  57.                 matrice[r][c]=n_cella;
  58.                 n_cella+=1;
  59.                 c-=1;
  60.             }
  61.             else{
  62.                 dir=1;
  63.                 c+=1;
  64.                 n_cella-=1;
  65.             }
  66.         }
  67.     }
  68.     for(r=0;r<rows;r++){
  69.         for(c=0;c<cols;c++){
  70.             cout<<matrice[r][c];
  71.         }
  72.         cout<<endl;
  73.     }
  74.     return 0;
  75. }



in runtime non succede nulla, infatti il programma non funziona ma facendo il debug mi segnala l'errore con l'istruzione:
Codice sorgente - presumibilmente Plain Text

  1. celle_tot=rows*cols;


ma il problema e' che qualsiasi cosa faccia con la variabile celle_tot mi genera l'errore, anche se le assegno un valore costante.

Grazie anticipatamente

P.S. l'esercizio richiedeva di riempire una matrice seguendo uno schema a spirale partendo dall'angolo in basso a sinistra.

Ultima modifica effettuata da orion3 il 02/11/2012 alle 17:58
PM Quote
Avatar
nessuno (Normal User)
Guru^2


Messaggi: 6404
Iscritto: 03/01/2010

Segnala al moderatore
Postato alle 18:20
Venerdì, 02/11/2012
1) r=rows

è sbagliato in quanto, in quel momento non si sa quanto vale rows (il cui input è successivo)

2) comunque r deve valere rows-1 dato che gli elementi vanno da 0 a rows-1

3) l'errore è comunque nel controllo dei valori di r e c nel tuo algoritmo ... rivedilo perché a un certo punto c diventa -1 e da qui l'errore ...


Ricorda che nessuno è obbligato a risponderti e che nessuno è perfetto ...
---
Il grande studioso italiano Bruno de Finetti ( uno dei padri fondatori del moderno Calcolo delle probabilità ) chiamava il gioco del Lotto Tassa sulla stupidità.
PM Quote
Avatar
orion3 (Normal User)
Rookie


Messaggi: 28
Iscritto: 16/04/2011

Segnala al moderatore
Postato alle 19:16
Venerdì, 02/11/2012
grazie per l'aiuto, il primo errore che hai trovato e' dovuto al fatto che ho modificato il programmma e ho dimenticato di cambiare quella dichiarazione, infatti prima di cambiarlo era giusto..comunque ho provato a modificare le condizioni e ho trovato qualche altra cosa che non andava nell'algoritmo ma non riesco a farlo partire perche' termina subito...:
Codice sorgente - presumibilmente C++

  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4.  
  5.  
  6.  
  7. int main()
  8. {
  9.     int rows,cols,dir=1,n_cella=1,r,c=0,celle_tot;
  10.     cout<<"Inserisci il numero di righe: ";
  11.     cin>>rows;
  12.     cout<<"Inserisci il numero di colonne: ";
  13.     cin>>cols;
  14.  
  15.     r=rows-1;
  16.  
  17.     vector <vector<int> > matrice (rows, vector<int>(cols,0));
  18.     celle_tot=rows*cols;
  19.     while (n_cella<celle_tot){
  20.         while(dir==1){
  21.             if(matrice[r][c]== 0 && r>=0){
  22.                 matrice[r][c]=n_cella;
  23.                 n_cella+=1;
  24.                 r-=1;
  25.             }
  26.             else{
  27.                 dir=2;
  28.                 r+=1;
  29.                 c+=1;
  30.                 n_cella-=1;
  31.             }
  32.         }
  33.         while(dir==2){
  34.             if(matrice[r][c]== 0 && c<cols){
  35.                 matrice[r][c]=n_cella;
  36.                 n_cella+=1;
  37.                 c+=1;
  38.             }
  39.             else{
  40.                 dir=3;
  41.                 c-=1;
  42.                 r+=1;
  43.                 n_cella-=1;
  44.             }
  45.         }
  46.         while(dir==3){
  47.             if(matrice[r][c]== 0 && r<rows){
  48.                 matrice[r][c]=n_cella;
  49.                 n_cella+=1;
  50.                 r+=1;
  51.             }
  52.             else{
  53.                 dir=4;
  54.                 r-=1;
  55.                 c-=1;
  56.                 n_cella-=1;
  57.             }
  58.         }
  59.         while(dir==4){
  60.             if(matrice[r][c]== 0 && c>=0){
  61.                 matrice[r][c]=n_cella;
  62.                 n_cella+=1;
  63.                 c-=1;
  64.             }
  65.             else{
  66.                 dir=1;
  67.                 c+=1;
  68.                 r-=1;
  69.                 n_cella-=1;
  70.             }
  71.         }
  72.     }
  73.     for(r=0;r<rows;r++){
  74.         for(c=0;c<cols;c++){
  75.             cout<<matrice[r][c];
  76.         }
  77.         cout<<endl;
  78.     }
  79.     return 0;
  80. }



se c=-1 l'if dovrebbe terminare senza controllare la posizione r,-1 della matrice, o mi sbaglio ? comunque esiste qualche altro algoritmo piu' semplice ?

Ultima modifica effettuata da orion3 il 02/11/2012 alle 19:20
PM Quote
Avatar
Premoli (Normal User)
Pro


Messaggi: 108
Iscritto: 25/06/2009

Segnala al moderatore
Postato alle 1:17
Sabato, 03/11/2012
Ciao in realtà ti sfugge qualcosa, l'algoritmo che hai trovato non mi sembra corretto, inoltre devi sapere che l'operatore && è cortocircuitato vale a dire che se in un'espressione hai ad esempio:

Codice sorgente - presumibilmente C/C++

  1. int x = 1;
  2. int y = 0;
  3. int z = 0;
  4.  
  5. if(x == y && y == z)
  6. {
  7.     //do something
  8. }



in questo caso y == z non viene proprio valutato in quanto si ha che x == y è già falso che implica che tutta l'espressione sarà falsa...
Quindi quando tu fai if(matrice[r][c]== 0 && c<cols) per come hai strutturato l'algoritmo avrai che ad un certo punto c sarà >= cols ma intanto r sarà diventata < di 0 quindi ti ritrovi a controllare posizioni fuori dai limiti della matrice, per correggere dovresti quanto meno scrivere in questo modo if(c<cols && matrice[r][c]== 0) in questo modo per il motivo che ti ho spiegato prima dovrebbe funzionare... Tuttavia ci sono ancora diversi errori nel codice.

Per quanto riguarda l'algoritmo la prima cosa che mi è venuta in mente è qualcosa del genere:

Codice sorgente - presumibilmente C++

  1. int completed = 0;
  2.  
  3. int nr = r;
  4. int nc = c;
  5.  
  6. int x = r;
  7. int y = 0;
  8.  
  9. while(completed < r * c)
  10. {
  11.         for(int i = 0; i < nr; i++)
  12.         {
  13.                 matrix[--x][y] = completed++;
  14.         }
  15.         for(int i = 0; i < nc - 1; i++)
  16.         {
  17.                 matrix[x][++y] = completed++;
  18.         }
  19.         for(int i = 0; i < nr - 1; i++)
  20.         {
  21.                 matrix[++x][y] = completed++;
  22.         }
  23.         for(int i = 0; i < nc - 2; i++)
  24.         {
  25.                 matrix[x][--y] = completed++;
  26.         }
  27.         nr-=2;
  28.         nc-=2;
  29. }



fammi sapere se è tutto chiaro

PM Quote
Avatar
orion3 (Normal User)
Rookie


Messaggi: 28
Iscritto: 16/04/2011

Segnala al moderatore
Postato alle 10:29
Sabato, 03/11/2012
grazie mille premoli, avevi ragione, funziona!...pero' non capisco, se l'and e' falsa eseguira' comunque l'else, indipendentemente dalla condizione che rende falsa l'espressione per cui non riesco a capire perche' incida cosi' tanto. Mi spiego meglio: io ho (matrice[r][c] ==0 && c<cols) ad un certo punto c sara' = a cols per cui uscira' dall'if ed eseguira' l'else che fara' diventare "c" di nuovo < cols e quindi passo alla prossima direzione senza controllare celle inesistenti perche' questo vale anche per la "r"....
Scusami se chiedo ma voglio capire bene :)
Poi questo problema vale anche per l'or giusto ?

Ultima modifica effettuata da orion3 il 03/11/2012 alle 10:40
PM Quote
Avatar
Premoli (Normal User)
Pro


Messaggi: 108
Iscritto: 25/06/2009

Segnala al moderatore
Postato alle 11:10
Sabato, 03/11/2012
Ciao, Beh non è affatto un problema, anzi... Comunque si anche l'or è cortocircuitato.

Però mi sa che non hai capito ancora come funziona, allora cerco di farti un esempio pratico sul tuo esercizio...
Allora mettiamo che io inserisca come numero di righe 2 e come numero di colonne 2, allora la mia situazione iniziale sarà:

passo 1:
dir = 1;
r = 1;
c = 0

ora entrerò nel primo while perché dir è uguale a 1.
A questo punto entro nel primo if e quello che succede è questo:

matrice[r][c]=n_cella;
n_cella+=1;
e decremento r di uno quindi al passo 2 avrò:
dir = 1;
r = 0;
c = 0;

Entrerò nuovamente nel primo while e nel primo if
assegno bla bla bla...
e decremento di uno r che però a questo punto sarà -1!!!

quindi al passo tre entrerò nuovamente nel primo while poi quando vado a fare il controllo del primo if succede che vado a controllare se matrice[-1][0] == 0 che è una posizione che non esiste...

scrivendo invece l'if in questo modo if(r>=0 && matrice[r][c]== 0) quello che succede al passo 3 è che quando vado a controllare se r >= 0 questo sarà falso e dato che && è cortocircuitato non andrà neanche a controllare se matrice[r][c] == 0 tanto già tutta l'espressione è falsa, evitando di far crashare il programma.

In generale comunque, quando hai questo genere di problemi ti conviene lanciare il debugger ed eseguire il programma passo passo, spesso aiuta a capire dove si trova il problema. In questo caso ti saresti sicuramente accorto del problema...

Ultima modifica effettuata da Premoli il 03/11/2012 alle 11:13
PM Quote
Avatar
orion3 (Normal User)
Rookie


Messaggi: 28
Iscritto: 16/04/2011

Segnala al moderatore
Postato alle 15:37
Sabato, 03/11/2012
grazie per la pazienza, ora mi e' tutto molto chiaro !! comunque il prof ci fa usare Qt e non ho molta confidenza perche' abbiamo iniziato da poco, io sono abituato al debugger di visual studio che permette di visualizzare il valore di tutte le variabili in qualsiasi istante di tempo...probabilmente lo fara' anche QtCreator ma devo ancora scoprirlo :)

Grazie mille per le nozioni :D !!

PM Quote