[RISOLTO] Segmentation fault (C++)

giuscri
Il sorgente che segue è lo svolgimento di un esercizio in cui mi si chiede di caricare da file la scomposizione degli interi nell'intervallo [2,200]. Precisa l'esercizio, in questo intervallo ciascun intero non ha più di tre fattori primi.
Il file "factorsrep.dat" è strutturato nel modo seguente:

primo_fattore esponente_1 (...) kesimo_fattore esponente_k -1 -1
etc.

Due righe qualsiasi ad esempio:

57 1 -1 -1
2 1 3 1 -1 -1

Per ciascuna riga devo calcolare il numero scomposto (57 nella prima riga d'esempio, 6 nella seconda) e caricare tutte le informazioni relative su un array di tipo fattore, dove fattore è la seguente struttura:


struct fattore{

	int numeroscomposto;
	int numerofattori;
	int fatt[3];
	int exp[3];

};




Ora, il codice l'ho scritto e compila. Quando eseguo però mi da un errore di segmentazione. Ho pensato che avessero potuto darmi qualche problema le istruzioni del tipo

fattore vettore[numero_posti];
vettore[j].fatt[k] = a; //con j e k due interi


ma non saprei come altro scrivere lo stesso "comando".



Qualche consiglio?

Risposte
claudio862
Probabilmente la variabile "i" supera il valore 198. Prova a stampare il suo valore ad ogni iterazione.


Un paio di osservazioni:

Metti degli spazi tra gli operatori, migliora la leggibilità:

num=num*pow((double) prime, esponente);
v[i].numerofattori++;
v[i].fatt[k]=prime;
v[i].exp[k]=esponente;
k++;


num = num * pow((double) prime, esponente);
v[i].numerofattori++;
v[i].fatt[k] = prime;
v[i].exp[k] = esponente;
k++;



In C++ le variabili si dichiarano "il più tardi possibile", in modo che siano confinate nello scope più interno possibile. k, presente, num sono usate solo dentro il ciclo do while, quindi dovresti dichiararle lì. Questo ti risparmia anche di reimpostare il loro valore alla fine del ciclo.
La variabile i è usata solo all'interno del ciclo, però il suo valore dipende dalla variabile v, che è fuori, quindi anche i va fuori dal ciclo. Però puoi dichiararla all'interno della funzione main(). E in generale variabili globali (cioè dichiarate fuori dalle funzioni) sono da evitare.

int main(){
    ifstream ingresso;
    int prime, esponente;

    const int N = 199;
    int i = 0;
    fattore v[N];

    ingresso.open("factorsrep.dat");

    ingresso >> prime >> esponente;

    do{
        int k = 0;
        bool presente = false;
        int num = 1;

        v[i].numerofattori=0;

        while(prime != -1 && esponente != -1){

            num = num * pow((double) prime, esponente);
            v[i].numerofattori++;
            v[i].fatt[k] = prime;
            v[i].exp[k] = esponente;
            k++;

            if(k > 3) {
                error();
                return 1;
            }

            ingresso >> prime >> esponente;
        }
      

        for(int j = 0; j < i; j++)
            if(v[j].numeroscomposto == num) {
                presente = true;
                break;
            }

        if(presente != true){
            v[i].numeroscomposto = num;
            i++;
        }

        ingresso >> prime >> esponente;

    } while(!ingresso.eof());

    // Qua "k", "presente" e "num" non sono più accessibili.

    ingresso.close();

    stampa(v);

    return 0;
}

giuscri
[OT]

In questo momento sono di fretta: controllerò più tardi. Intanto volevo chiedere: dichiarare variabili all'interno di un ciclo non porta a sprecare memoria inutilmente? Mi aspetto che


for(int j=0;j<200;j++){

  char a = 'a';

}



occupi 200 byte in più rispetto a


char a = 'a';

for(int j=0;j<200;j++)



Mi rendo conto che sono problemi che forse per una macchina moderna sono di pochissimo conto, ma era una curiosità.

[/OT]

claudio862
No, perché quando una variabile esce dallo scope viene distrutta.

{ // Nuovo scope
int a = 3;
} // Fine scope, qua "a" viene distrutta.


Le variabili locali sono gestite con uno stack. Quando il programma entra in un nuovo scope, nuovo spazio viene allocato sullo stack per le variabili locali. Quando il programma esce dallo scope lo stack viene "svuotato". Quindi nell'esempio qui sopra ci sarà sempre al massimo una variabile "int a" in memoria. L'allocazione e deallocazione sullo stack sono praticamente istantanee.

giuscri
"claudio86":
Quando una variabile esce dallo scope viene distrutta.

{ // Nuovo scope
int a = 3;
} // Fine scope, qua "a" viene distrutta.


Le variabili locali sono gestite con uno stack. Quando il programma entra in un nuovo scope, nuovo spazio viene allocato sullo stack per le variabili locali. Quando il programma esce dallo scope lo stack viene "svuotato". Quindi nell'esempio qui sopra ci sarà sempre al massimo una variabile "int a" in memoria. L'allocazione e deallocazione sullo stack sono praticamente istantanee.


Ti ringrazio per avermi tolto la curiosità.

"claudio86":
Probabilmente la variabile "i" supera il valore 198.


Grande!

Rispondi
Per rispondere a questa discussione devi prima effettuare il login.