Newsgroup: it.comp.lang.c++
Titolo: segmentation fault

Hello world!
 
Come faccio a scovare un errore di segmentation fault?
Me lo dà questa routine.
Il problema si verifica quando vado ad accedere a testo[][], infatti se 
commento tutti i vari cout non viene segnalato errore, in pratica la 
matrice testo[][] sembra essere vuota, o perlomeno il programma non 
punta alle giuste locazioni.
 
	for(i=1;i<50;i++)
	{
		a=rand()%2;
		b=tur[i];
		cout<<testo [b][1]<<endl;
		if(a==0)
		{
			cout<<testo [b][2]<<endl;
			cout<<testo [b][3]<<endl;
		}
		if(a==1)
		{
			cout<<testo [b][3]<<endl;
			cout<<testo [b][2]<<endl;
		}
		cout<<endl;
	}
 
 
 
a seguire, se può aiutare, il programma completo.
 
//
//
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <string>
using namespace std;
 
string testo [50] [3];
unsigned int i=0,j=0,k=0;
unsigned int tur[50],n,a,b;
string s;
int main(int argc, char** argv) {
	cout <<"Si comincia!";
	cout << endl;
	cout << endl;
	system("PAUSE");
 
     ifstream f("file.txt");
     if(!f)
	{
         cout<<"Il file non esiste!";
         return -1;
     }
	k=j=0;
     while(f.good()) //fino a quando c'è qualcosa da leggere ..
     {
         //legge tutta la riga dal file e la mette nella variabile s
         getline(f, s);
         k=k++;
         j=j++;
         if(j==4)
		{
			j=1;
		}
         testo [k][j]=s;
         cout<<testo [k][j]<<endl;
     }
 
	b=0;
	for(i=1;i<50;i++)
	{
		tur[i]=i;
	}
	for(i=1;i<=50;i++)
	{
		a=(rand()%50)+1;
		b=tur[a];
		tur[a]=tur[i];
		tur[i]=b;
	}
	system("PAUSE");
 
	// fino a qui funziona, testo[][] e tur[] sono pieni
 
	for(i=1;i<50;i++)
	{
		a=rand()%2;
		b=tur[i];
		cout<<testo [b][1]<<endl;
		if(a==0)
		{
			cout<<testo [b][2]<<endl;
			cout<<testo [b][3]<<endl;
		}
		if(a==1)
		{
			cout<<testo [b][3]<<endl;
			cout<<testo [b][2]<<endl;
		}
		cout<<b<<endl;
	}
     f.close(); //chiude il file
	return 0;
}


 
un consiglio "a prescindere" : un debugger, qualche breakpoint un po' di 
run passo passo e passa la paura!
 
tanto per gradire mi trovo abbastanza bene con codeblocks ( sia per 
windows che per linux ), ma e' anche una questione di gusti personali
 


al momento sto usando Dev C++ portable, nella versione aggiornata, 
Codeblocks non riesco a settarlo per windows 8.1, mi dice che non trova 
il compilatore, magari se ci perdo tempo ci riesco, o se no mi sposto su 
una macchina Linux.
Però anche con Visual Studio su una macchina con windows 7 mi dà lo 
stesso problema e non riesco a fare il debug.
Cmq... come cavolo fa a perdersi i dati di una matrice, o i puntatori 
alla matrice,  che solo poche righe di codice prima era piena???
 
..

 ..
 

       a=(rand()%50)+1;
 
torna anche 50...
 
Ciao Jack
-- 
Yoda of Borg am I! Assimilated shall you be! Futile resistance is, hmm?

Il 11/05/2015 21:50, Arkannen ha scritto:
Ho risolto!
Grazie ai vostri suggerimenti sono andato a vedere cosa capitava agli 
indici e mi sono accorto che la routine che segue memorizzava solo 
testo[0][0] perché
 
k=k++;
j=j++;
 
(ovviamente) non incrementavano nulla(!), ho sostituito le linee con
 
k++;
j++;
 
inoltre ho dovuto dimensionare
 
string testo [52] [3];
 
invece di
 
string testo [50] [3];
 
ossia 2 in più di 50, che sono quelli effettivamente usati.
E questo non ho capito perché.
 
Di nuovo grazie per i suggerimenti, io programmo ogni morte di Papa e 
ogni volta con linguaggi sempre diversi, per cui faccio errori sciocchi, 
di altre cose spesso poi ignoro i perché.
 
A seguire la routine rivista, corretta e funzionante, se può servire a 
qualcuno.
 
// questa routine rimescola domande e risposte di un test con 50 domande 
e due opzioni per ogni risposta
 
#include <iostream>
#include <stdlib.h>
#include <fstream>
#include <string>
using namespace std;
 
string testo [52] [3];
unsigned int i=0,j=0,k=0;
unsigned int tur[50],n,a,b;
string s;
int main(int argc, char** argv) {
	cout <<"Si comincia!";
	cout << endl;
	cout << endl;
	system("PAUSE");
 
     ifstream f("file.txt");
     if(!f)
	{
         cout<<"Il file non esiste!";
         return -1;
     }
 
     for (k=1;k<=50;k++)
	{
         for (j=1;j<=3;j++)
		{
			getline(f, s);
             testo [k][j]=s;
             cout<<testo [k][j]<<endl;
         }
	}
 
	b=0;
	for(i=1;i<=50;i++)
	{
		tur[i]=i;
	}
	system("PAUSE");
	for(i=1;i<=50;i++)
	{
		a=(rand()%50)+1;//qui avviene lo scambio in maniera casuale delle
		b=tur[a]; //locazioni dell'array
		tur[a]=tur[i];
		tur[i]=b;
	}
 
	for(i=1;i<=50;i++)
	{
		a=rand()%2;
		b=tur[i];
		cout<<i<<" ** "<<testo [b][1]<<endl;
		if(a==0)
		{
			cout<<testo [b][2]<<endl;
			cout<<testo [b][3]<<endl;
		}
		if(a==1)
		{
			cout<<testo [b][3]<<endl;
			cout<<testo [b][2]<<endl;
		}
 
	}


On 05/11/15 21:50, Arkannen wrote:
 > Hello world!
 >
 > Come faccio a scovare un errore di segmentation fault?
 
Una o piu' tra:
 
A) togli gli array "stile C" ed usi delle classi (tipo std::vector, 
std:array, ecc...) che forniscano dei metodi di accesso controllato;
B) usi un debugger;
C) usi uno strumento tipo Valgrind (dico "tipo", perche' ho letto che 
usi Windows e non credo vadano d'accordo).
 
 
 
 > Il problema si verifica quando vado ad accedere a testo[][],
 
Anche prima:
 
 > ...
 > unsigned int tur[50],n,a,b;
 > ...
 >      for(i=1;i<50;i++)
 >      {
 >          tur[i]=i;
 >      }
 > ...
 
Gli elementi di tur (come di tutti gli altri array) vanno da 0 a 49, non 
da 1 a 50.
 
 
 
  bye

 da 1 a 50.
 
il for() lo fa andare da 1 a 49.
E' dopo che tenta di accedere con un indice che va da 1 a 50  (
(rand()%50)+1 )...


 std:array, ecc...) che forniscano dei metodi di accesso controllato;
 
temo che il mio sia un problema di forma mentis.
Ho iniziato a programmare negli anni 80 con Fortran e Basic, poi ho 
lavorato con SQL fino al 2000, e ad oggi scrivo per lo più routine in 
assembler per i microcontrollori, per cui la programmazione imperativa è 
nel mio DNA.
Non è facile arrabbattarsi con classi, oggetti, ereditarietà per chi a 
malapena ha assimilato il concetto di puntatore con il Pascal.
Uso il C++ quando devo scrivere due righe, proprio perché permette 
ancora la programmazione imperativa.
 
..
 

 ancora la programmazione imperativa.
 
Prova.
 
Certo "scrivere/inventare/immaginare" gerarchie di classi non e' cosi' 
facile, ma forse scopriresti che utilizzare quelle basi fornite ad es. 
dall'STL non e' affatto difficile (e non mette a repentaglio 
l'"imperativita'" del tuo codice :).
Con quelle puoi anche dimenticare in gran parte i puntatori.
 
  bye