Problema con errore di segmentazione, core dump creato

di il
14 risposte

Problema con errore di segmentazione, core dump creato

Buongiorno,
premetto di essere alle prime armi.
Ho dei problemi con il seguente codice sorgente:

#include <stdio.h>
#include <string.h>


struct dato{
        int decimale;
        char* binario;
};

void binario(char* risultato, int n) {

        while(n>0){
                *risultato = n%2;
                n = n/2;
                risultato++;
        }
}

int main(){


        struct dato numero;
        char nomefile_input[100];
        int* numero_input;

        printf("Da quale file vuoi che stampi?\n");
        scanf("%s", nomefile_input);

        FILE* input = fopen(nomefile_input, "r");

        if(input == NULL){
                fprintf(stderr, "Nome del file non valido");
        }

        while(!feof(input)){
                fscanf(input, "%d", numero_input);
                        numero.decimale = *numero_input;
                        binario(numero.binario, *numero_input);
                        if(feof != 0);
                        printf("\n%d %s", numero.decimale, numero.binario);
	}
return 0;
}
Il programma si propone di leggere una lista di numeri da un file e stampare i numeri letti in decimale e in binario.
Il codice viene compilato senza errori e quando eseguito restituisce "errore di segmentazione core dump creato" subito dopo aver ricevuto il nome del file da cui leggere i dati.

Sapreste aiutarmi? Presumo che il problema sia nelle dimensioni delle stringhe usate che da qualche parte non sono coerenti.
Grazie

14 Risposte

  • Re: Problema con errore di segmentazione, core dump creato

    Perché usi un puntatore per numero_input ?
  • Re: Problema con errore di segmentazione, core dump creato

    Grazie oregon per la risposta, ho aggiornato il codice inserendo la correzione e rivedendo un altro paio di imprecisioni, in particolare il ciclo while stampava due volte l'ultima riga, ho aggiornato l'ultimo ciclo while così:
    
      while(!feof(input)){
                    fscanf(input, "%d", &numero_input);
                            numero.decimale = numero_input;
                            binario(numero.binario, numero_input);
                            if(feof(input) == 0){
                                    printf("%d %s\n", numero.decimale, numero.binario);
                            }
       }
    
    il problema di core dump è risolto ma ora ottengo come stampa per "numero.binario" una serie di punti di domanda.
  • Re: Problema con errore di segmentazione, core dump creato

    Stai usando dei puntatori all'interno della struttura senza avere allocato la memoria prima.

    Ma poi perché utilizzi quella struttura?

    Posta nuovamente TUTTO il codice modificato e compilabile.
  • Re: Problema con errore di segmentazione, core dump creato

    
    #include <stdio.h>
    #include <string.h>
    
    
    struct dato{
            int decimale;
            char* binario;
    };
    
    void binario(char* risultato, int n) {
    
            while(n>0){
                    *risultato = '0' + n%2;
                    n = n/2;
                    risultato++;
            }
    }
    
    int main(){
    
    
            struct dato numero;
            char nomefile_input[100];
            int numero_input;
    
            printf("Da quale file vuoi che stampi?\n");
            scanf("%s", nomefile_input);
    
            FILE* input = fopen(nomefile_input, "r");
    
            if(input == NULL){
                    fprintf(stderr, "Nome del file non valido");
            }
    
            while(!feof(input)){
                    fscanf(input, "%d", &numero_input);
                            numero.decimale = numero_input;
                            binario(numero.binario, numero_input);
                            if(feof(input) == 0){
                                    printf("%d %s\n", numero.decimale, numero.binario);
                            }
    
            }
    
            fclose(input);
            return 0;
    }
    
    Ecco qua.
    Lo scopo è quello di fare esercizio con puntatori, strutture, istruzioni per la lettura e scrittura da/su file e divisione del codice in più file .c diversi, il programma non deve avere nessuna utilità pratica.
  • Re: Problema con errore di segmentazione, core dump creato

    Ecco ... stai passando un puntatore senza avere allocato la memoria

    char *binario

    non puoi utilizzarlo se non punta a memoria allocata. Rivedi il funzionamento dei puntatori.
  • Re: Problema con errore di segmentazione, core dump creato

    Visto che vuoi svolgere l'esercizio su più file puoi prevedere una coppia binario.h/binario.c dove raccogliere le funzioni per la conversione.
    Il file binario.h potrebbe essere una cosa del genere:
    #ifndef BINARIO_H_INCLUDED
    #define BINARIO_H_INCLUDED
    
    #include <stdlib.h>
    
    /* valgono per numeri fino a 32 bit */
    #define MAX_BITS    32
    #define MAX_CIFRE   10
    
    void binario( char *s, int n );
    
    #endif // BINARIO_H_INCLUDED
    
    In questo modo potresti chiamare la funzione da main.c semplicemente includendo "binario.h".
    Tra l'altro, potresti includere la possibilità di avere il buffer per la stringa del numero in formato binario "incorporato" nella funzione binario() stotto forma di spazio statico da usare nel caso che il parametro s sia NULL, così potresti anche risparmiarti l'onere di pensare alla gestione del buffer in main().
    #include <stdio.h>
    #include "binario.h"
    
    int main() {
        char nomeFInput[] = "prova.txt";    /* preimpostato, SOLO per brevita' */
        FILE* fIn = NULL;                   /* fIn = file in input */
    
        if( (fIn=fopen(nomeFInput,"r")) != NULL ) {
            int nIn;                   /* nIn = numero in input */
            int ff;                    /* ff = fine file */
    
            while( !(ff=feof(fIn)) ) {
                /* rileva il prossimo numero */
                fscanf( fIn, "%d", &nIn );
    
                /* mostra il risultato */
    
                /* ci pensa la libreria standard */
                printf( "decimale: %d\n", nIn );
                /* demanda a una nostra funzione, nei file binario.h/binario.c */
                printf( "binario:  %s\n\n", binario(NULL,nIn) );
            }
    
            fclose( fIn ); fIn = NULL; // chiude il file
        } else fprintf( stderr, "Nome del file non valido\n\n" );
    
        getchar(); /* attende che si prema "invio" prima di uscire */
        return 0;
    }
    Nel file binario.c ci sarebbe l'implementazione della funzione binario() e di una funzione "accessoria" per invertire l'ordine delle cifre nella stringa col numero in formato binario.
    #include "binario.h"
    
    char *agnirts( char *s ); // prototipo
    
    /*==============================================================================
    Imposta in s la rappresentazione come stringa di cifre binarie del valore
    passato in n.
    ==============================================================================*/
    
    char *binario( char *s, int n ) {
        static char ss[MAX_BITS+2]; // "ss" = stringa statica
        int neg = n<0;
        char *p;
    
        if( s == NULL ) s = ss; // in mancanza di un buffer, usiamo quello statico
    
        /* mistero, per non inquietare i moderatori :) */
    
        return s;
    }
    
    /*==============================================================================
    Rovescia la stringa s, riscrivendola "all'indietro".
    Restituisce l'indirizzo alla stessa stringa ricevuta in s.
    ==============================================================================*/
    
    char *agnirts( char *s ) {
        if( s != NULL ) { /* s deve essere un puntatore valido */
           /* mistero, per non inquietare i moderatori :) */
        }
    
        return s;
    }
    
  • Re: Problema con errore di segmentazione, core dump creato

    Curiosando, ho trovato su http://www.cprogramming.com/snippets/source-code/convert-an-integer-into-binary-representation un metodo di conversione in binario che m'è parso "intrigante". Con un piccolo adattamento per averne l'uscita su stringa anziché in console può diventare una cosa di questo genere:
    char *binario( int n ) {
        static char s[sizeof(int)*8+1];
        int i, j;
    
        for( i=0, j=sizeof(int)*8-1; j>=0 ; i++, j-- )
            s[i] = (1<<j)&n?'1':'0';
        s[i] = '\0';
    
        return s;
    }
  • Re: Problema con errore di segmentazione, core dump creato

    Invece di riempire di 0 a sinistra il risultato, si può usare lo spazio, con qualche modifica

    char ch = 0x20;

    s = (1 << j)&n ? ch='0','1' : ch;
  • Re: Problema con errore di segmentazione, core dump creato

    Sì. Credo però che l'idea di chi ha messo insieme quella funzione fosse di visualizzare tutti i bit che costituiscono il valore. compresi quelli "non significativi". Infatti, se usi un unsigned short ti dà 16 cifre e se usi un unsigned char solo 8.

    Ah, già che siamo qui... non mi è chiaro quel ch='0','1' (nel senso che non ho mai visto usare un assegnamento con due valori separati da una virgola). Puoi spiegare come funziona?

    s = (1 << j)&n ? ch='0','1' : ch;
  • Re: Problema con errore di segmentazione, core dump creato

    AldoBaldo ha scritto:


    ... visualizzare tutti i bit che costituiscono il valore. compresi quelli "non significativi"
    Questo è evidente dato che tratta sizeof(int)*8 caratteri (uno per bit)
    come funziona?
    Non è una "doppia assegnazione" (non avrebbe senso). La virgola separa due parti eseguite in modo indipendente, prima esegue l'assegnazione a ch e poi restituisce '1' per la parte vera di ?
  • Re: Problema con errore di segmentazione, core dump creato

    Cioè equivarrebbe a questo?
    char ch = 0x20;
    
    if( (i<<j)&n ) {
        ch = '0';
        s[i] = '1';
    }
    else {
        s[i] = ch;
    }
    Se ci ho preso, devo ammettere che non mi sarebbe mai venuto in mente di "sintetizzarlo" nella forma che hai proposto.
  • Re: Problema con errore di segmentazione, core dump creato

    È così...
  • Re: Problema con errore di segmentazione, core dump creato

    Pazzesco! Ogni volta che credi di avere una "buona conoscenza" di qualcosa salta fuori che te ne eri perso un pezzo! Be', aggiungo anche questo alla "buona conoscenza", nell'attesa che salti fuori il pezzo successivo...
  • Re: Problema con errore di segmentazione, core dump creato

    Il linguaggio "permette" tante cose ... più o meno come quando scrivi
    
    	int i, x;
    
    	for (i = x = 0; x++, i < 10; i++)
    		printf("%d\n", x);
    
    Ti sembrerà strana la posizione di x++ ma non è proprio così
Devi accedere o registrarti per scrivere nel forum
14 risposte