Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 14
  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2014
    Messaggi
    6

    [C] Errore di segmentazione su accesso a memoria allocata

    Salve a tutti, sono alle prime armi col linguaggio C e sto preparando alcuni progetti per l'università.
    Il programma non va avanti ed eseguendo un debug ho riscontrato un errore di segmentazione al rigo 42, ho messo una freccetta nel codice per indicarvela.
    Nel codice c'è anche scritta la traccia, non è svolta tutta poichè provavo le prime function e mi sono imbattuto in questo errore.

    Spero che possiate aiutarmi, grazie anticipatamente.

    codice:
    /*Si vuole simulare l’archivio di chiamate di un gestore telefonico. L’archivio risulta  
    mensile (31 giorni) . Ogni giorno vengono effettuate al massimo 10 chiamate e il  
    costo al minuto di una chiamata è di 10 centesimi. Ogni chiamata è identificata dal  
    numero chiamante, il numero ricevente, la durata della chiamata. Provvedere  
    all’implementazione dell’algoritmo per la simulazione dell’archivio.  
    Permettere, inoltre, all’utente di:  
    • Dato un numero telefonico visualizzare tutte le chiamate con le relative  
    informazioni in un singolo giorno  
    • Dato un giorno e un numero telefonico visualizzare il costo totale delle  
    chiamate (usare un algoritmo incrementale ricorsivo).  
    L’archivio può anche essere inizializzato con informazioni casuali. Effettuare almeno  
    due test per ognuna delle opzioni dell’utente.*/
    
    
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #define chiamate 10
    #define giorni 30
    
    
    char *numeri[]={"3341431454", "3462154556", "3911177368", "3338083794", "3398379801"};
    
    
    typedef struct{ //Dichiarazione struct con io dati delle chiamate.
    char *chiamante;
    int ricevente;
    int durata;
    }Dati;
    
    
    typedef struct{ //Dichiarazione struct contenente l'archivio mensile.
    Dati *elenco[chiamate][giorni];
    }Archivio;
    
    
    
    
    Archivio creaDati(){ //Funzione per creare l'archivio, essa restituisce una struct di tipo Archivio.
        Archivio archivio;
        srand(time(NULL));
        int i=0, j=0, k=0;
        for (i=0; i<=giorni;){ //Ciclo for per riempire i campi Dati, una rand genera casualmente l'indice j dei numeri, 
                               //una rand genera casualmente numeri che ricevono la chiamata ed un'ultima genera la durata.
            for (k=0; k<chiamate; k++){
                j=rand()%5; 
     ---->        archivio.elenco[k][i]->chiamante = numeri[j];
                archivio.elenco[k][i]->ricevente = 1000000+rand()%999999+1;
                archivio.elenco[k][i]->durata = rand()%121;
            }
        }
        return archivio;
    }
    
    
    void stampaDati(Archivio archivio){ //Procedura per stampare l'archivio, prende come input una struct di tipo Archivio.
        int i=0, k=0;
        for (i=0; i<=giorni;){
            printf("\n\n\t\t----------[GIORNO %d]----------\n\n      CHIAMANTE\t\tRICEVENTE\t\tDURATA", i+1);
            for (k=0; k<chiamate; k++){
                printf("\n[C.%d] %s\t%d\t\t\t%d\tmin.", k+1, archivio.elenco[k][i]->chiamante, archivio.elenco[k][i]->ricevente, archivio.elenco[k][i]->durata);
            }
        printf("\n\n\t\tPremi invio per scorrere l'elenco.\n\t\t    Premi 'e' per ritornare.\n");
        getchar();
        if (getchar()=='e')
            break;
        else
                i++;
        }
    }
    
    
    void stampaElenco(){ //Procedura per stampare l'elenco dei numeri.
        int i=0;
        printf("I numeri presenti nel database sono i seguenti:\n");
        for (i=0; i<5; i++)
            printf("[N%d]  (+39)%s\n", i+1, numeri[i]);
        getchar();
    }
    
    
    void main(){
    Archivio simula; //Dichiaro una variabile di tipo Archivio.
    stampaElenco();  //Stampo l'elenco.
    simula=creaDati(); //Creo i dati.
    stampaDati(simula); //Stampo i dati.
    return 0;
    }

  2. #2
    Utente di HTML.it L'avatar di minomic
    Registrato dal
    Nov 2010
    Messaggi
    635
    Ciao,
    i problemi nel codice sono diversi, ma il principale è che non c'è alcuna chiamata alla funzione malloc. Se non allochi la memoria, come puoi poi andarci a scrivere qualcosa? Per forza ti dà l'errore di segmentazione!
    Inoltre è sbagliato anche il modo in cui copi le stringhe: non si usa l'operatore = ma la funzione strcpy.

  3. #3
    Utente di HTML.it L'avatar di Alex'87
    Registrato dal
    Aug 2001
    residenza
    Verona
    Messaggi
    5,802
    Oltre a quanto detto da minomic, un suggerimento:

    codice:
    Archivio simula; //Dichiaro una variabile di tipo Archivio.
    stampaElenco();  //Stampo l'elenco.
    simula=creaDati(); //Creo i dati.
    stampaDati(simula); //Stampo i dati.
    Commenti di questo tipo sono solo inutili, non perderci tempo. Commenta le parti ostiche, non l'ovvio!
    SpringSource Certified Spring Professional | Pivotal Certified Enterprise Integration Specialist
    Di questo libro e degli altri (blog personale di recensioni libri) | ​NO M.P. TECNICI

  4. #4
    Utente di HTML.it
    Registrato dal
    Sep 2014
    Messaggi
    6
    Quote Originariamente inviata da minomic Visualizza il messaggio
    Ciao,
    i problemi nel codice sono diversi, ma il principale è che non c'è alcuna chiamata alla funzione malloc. Se non allochi la memoria, come puoi poi andarci a scrivere qualcosa? Per forza ti dà l'errore di segmentazione!
    Inoltre è sbagliato anche il modo in cui copi le stringhe: non si usa l'operatore = ma la funzione strcpy.
    Ciao, grazie per la risposta. Non ho mai usato la chiamata malloc, ho visto un esempio di codice, così può andare bene?
    codice:
    for (i=0; i<=giorni; i++) 
          for (k=0; k<chiamate; k++) 
                 archivio.elenco[k][i] = (Dati*) malloc ( sizeof(Dati) ) ; 

    Quote Originariamente inviata da Alex'87 Visualizza il messaggio
    Oltre a quanto detto da minomic, un suggerimento:

    codice:
    Archivio simula; //Dichiaro una variabile di tipo Archivio.
    stampaElenco();  //Stampo l'elenco.
    simula=creaDati(); //Creo i dati.
    stampaDati(simula); //Stampo i dati.
    Commenti di questo tipo sono solo inutili, non perderci tempo. Commenta le parti ostiche, non l'ovvio!
    Grazie, seguirò il tuo consiglio.

  5. #5
    Utente di HTML.it L'avatar di minomic
    Registrato dal
    Nov 2010
    Messaggi
    635
    Diciamo che ogni volta che vuoi usare una struct Dati devi allocare il campo "chiamante". Però non mi è molto chiaro il motivo per cui, in Archivio, fai

    codice:
    Dati *elenco[chiamate][giorni];

    Sarebbe un puntatore a un array bi-dimensionale? Secondo me volevi solo una matrice, nel qual caso togli l'asterisco.

  6. #6
    Utente di HTML.it
    Registrato dal
    Sep 2014
    Messaggi
    6
    Quote Originariamente inviata da minomic Visualizza il messaggio
    Diciamo che ogni volta che vuoi usare una struct Dati devi allocare il campo "chiamante". Però non mi è molto chiaro il motivo per cui, in Archivio, fai

    codice:
    Dati *elenco[chiamate][giorni];
    Sarebbe un puntatore a un array bi-dimensionale? Secondo me volevi solo una matrice, nel qual caso togli l'asterisco.
    In pratica volevo creare un elenco di 31 giorni in cui in ogni giorno vi sono 10 telefonate, in questo modo per gli altri punti del problema posso scegliere giorno e numero da input e stampare le informazioni che mi servono.

    Per quanto riguarda il codice, l'ho modificato in questo modo (ho riportato solo la funzione interessata):
    codice:
    Archivio creaDati(){ //Funzione per creare l'archivio, essa restituisce una struct di tipo Archivio.     int i=0, j=0, k=0;
        Archivio archivio;
        for (i=0; i<=giorni; i++)
            for (k=0; k<chiamate; k++)
              archivio.elenco[k][i].chiamante=malloc(sizeof(Dati));
        srand(time(NULL));
        for (i=0; i<=giorni;){ //Ciclo for per riempire i campi Dati, una rand genera casualmente l'indice j dei numeri,
                               //una rand genera casualmente numeri che ricevono la chiamata ed un'ultima genera la durata.
            for (k=0; k<chiamate; k++){
                j=rand()%5;
                strcpy(archivio.elenco[k][i].chiamante, numeri[j]);
                archivio.elenco[k][i].ricevente = 1000000+rand()%999999+1;
                archivio.elenco[k][i].durata = rand()%121;
            }
        }
        return archivio;
    }
    Ora il programma non va in crash ma mi esegue solo la prima procedura per la stampa dell'elenco e non esegue altro...
    Ultima modifica di Enzo93; 16-09-2014 a 16:19

  7. #7
    Utente di HTML.it L'avatar di minomic
    Registrato dal
    Nov 2010
    Messaggi
    635
    Prova a postare il codice completo nella sua ultima versione, così gli diamo un'occhiata.

  8. #8
    Utente di HTML.it
    Registrato dal
    Sep 2014
    Messaggi
    6
    Eccolo...
    codice:
    /*Si vuole simulare l’archivio di chiamate di un gestore telefonico. L’archivio risultamensile (31 giorni) . Ogni giorno vengono effettuate al massimo 10 chiamate e il
    costo al minuto di una chiamata è di 10 centesimi. Ogni chiamata è identificata dal
    numero chiamante, il numero ricevente, la durata della chiamata. Provvedere
    all’implementazione dell’algoritmo per la simulazione dell’archivio.
    Permettere, inoltre, all’utente di:
    • Dato un numero telefonico visualizzare tutte le chiamate con le relative
    informazioni in un singolo giorno
    • Dato un giorno e un numero telefonico visualizzare il costo totale delle
    chiamate (usare un algoritmo incrementale ricorsivo).
    L’archivio può anche essere inizializzato con informazioni casuali. Effettuare almeno
    due test per ognuna delle opzioni dell’utente.*/
    
    
    
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <string.h>
    #define chiamate 10
    #define giorni 30
    
    
    char *numeri[]={"3341431454", "3462154556", "3911177368", "3338083794", "3398379801"};
    
    
    typedef struct{ //Dichiarazione struct con io dati delle chiamate.
    char *chiamante;
    int ricevente;
    int durata;
    }Dati;
    
    
    typedef struct{ //Dichiarazione struct contenente l'archivio mensile.
    Dati elenco[chiamate][giorni];
    }Archivio;
    
    
    
    
    Archivio creaDati(){ //Funzione per creare l'archivio, essa restituisce una struct di tipo Archivio.
        int i=0, j=0, k=0;
        Archivio archivio;
        for (i=0; i<=giorni; i++)
            for (k=0; k<chiamate; k++)
              archivio.elenco[k][i].chiamante=malloc(sizeof(Dati));
        srand(time(NULL));
        for (i=0; i<=giorni;){ //Ciclo for per riempire i campi Dati, una rand genera casualmente l'indice j dei numeri,
                               //una rand genera casualmente numeri che ricevono la chiamata ed un'ultima genera la durata.
            for (k=0; k<chiamate; k++){
                j=rand()%5;
                strcpy(archivio.elenco[k][i].chiamante, numeri[j]);
                archivio.elenco[k][i].ricevente = 1000000+rand()%999999+1;
                archivio.elenco[k][i].durata = rand()%121;
            }
        }
        return archivio;
    }
    
    
    void stampaDati(Archivio archivio){ //Procedura per stampare l'archivio, prende come input una struct di tipo Archivio.
        int i=0, k=0;
        for (i=0; i<=giorni;){
            printf("\n\n\t\t----------[GIORNO %d]----------\n\n      CHIAMANTE\t\tRICEVENTE\t\tDURATA", i+1);
            for (k=0; k<chiamate; k++){
                printf("\n[C.%d] %s\t%d\t\t\t%d\tmin.", k+1, archivio.elenco[k][i].chiamante, archivio.elenco[k][i].ricevente, archivio.elenco[k][i].durata);
            }
        printf("\n\n\t\tPremi invio per scorrere l'elenco.\n\t\t    Premi 'e' per ritornare.\n");
        getchar();
        if (getchar()=='e')
            break;
        else
                i++;
        }
    }
    
    
    void stampaElenco(){ //Procedura per stampare l'elenco dei numeri.
        int i=0;
        printf("I numeri presenti nel database sono i seguenti:\n");
        for (i=0; i<5; i++)
            printf("[N%d]  (+39)%s\n", i+1, numeri[i]);
        getchar();
    }
    
    
    void main(){
    Archivio simula;
    stampaElenco();
    simula=creaDati();
    stampaDati(simula);
    return 0;
    }
    Grazie ancora per l'aiuto...

  9. #9
    Utente di HTML.it L'avatar di minomic
    Registrato dal
    Nov 2010
    Messaggi
    635
    Così funziona:

    codice:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <string.h>
    #define chiamate 10
    #define giorni 30
    
    
    
    
    char *numeri[]= {"3341431454", "3462154556", "3911177368", "3338083794", "3398379801"};
    
    
    
    
    typedef struct  //Dichiarazione struct con io dati delle chiamate.
    {
        char *chiamante;
        int ricevente;
        int durata;
    } Dati;
    
    
    
    
    typedef struct  //Dichiarazione struct contenente l'archivio mensile.
    {
        Dati elenco[chiamate][giorni];
    } Archivio;
    
    
    
    
    
    
    
    
    Archivio creaDati()  //Funzione per creare l'archivio, essa restituisce una struct di tipo Archivio.
    {
        int i=0, j=0, k=0;
        Archivio archivio;
    
    
        for (i=0; i<giorni; i++)
        {
            for (k=0; k<chiamate; k++)
            {
                archivio.elenco[k][i].chiamante=malloc(sizeof(Dati));
                j=rand()%5;
                strcpy(archivio.elenco[k][i].chiamante, numeri[j]);
                archivio.elenco[k][i].ricevente = 1000000+rand()%999999+1;
                archivio.elenco[k][i].durata = rand()%121;
            }
        }
        return archivio;
    }
    
    
    
    
    void stampaDati(Archivio archivio)  //Procedura per stampare l'archivio, prende come input una struct di tipo Archivio.
    {
        int i=0, k=0;
        for (i=0; i<=giorni;)
        {
            printf("\n\n\t\t----------[GIORNO %d]----------\n\n      CHIAMANTE\t\tRICEVENTE\t\tDURATA", i+1);
            for (k=0; k<chiamate; k++)
            {
                printf("\n[C.%d] %s\t%d\t\t\t%d\tmin.", k+1, archivio.elenco[k][i].chiamante, archivio.elenco[k][i].ricevente, archivio.elenco[k][i].durata);
            }
            printf("\n\n\t\tPremi invio per scorrere l'elenco.\n\t\t    Premi 'e' per ritornare.\n");
            getchar();
            if (getchar()=='e')
                break;
            else
                i++;
        }
    }
    
    
    
    
    void stampaElenco()  //Procedura per stampare l'elenco dei numeri.
    {
        int i=0;
        printf("I numeri presenti nel database sono i seguenti:\n");
        for (i=0; i<5; i++)
            printf("[N%d]  (+39)%s\n", i+1, numeri[i]);
        getchar();
    }
    
    
    
    
    int main()
    {
        srand(time(NULL));
    
    
        Archivio simula;
        stampaElenco();
        simula = creaDati();
        stampaDati(simula);
        return 0;
    }

    C'è ancora qualcosa di sbagliato (secondo me) nel fatto che premendo 'e' non esce, comunque dovresti riuscire a sistemare facilmente.
    Il problema era nel ciclo for: avevi messo i<=giorni mentre deve essere i<giorni. Ricordati che si va da 0 a (giorni-1).
    E poi c'erano due doppi cicli for, mentre uno è sufficiente.

  10. #10
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,465
    Quote Originariamente inviata da minomic Visualizza il messaggio
    Così funziona:
    Ma questo

    archivio.elenco[k][i].chiamante=malloc(sizeof(Dati));



    non ha molto senso ...
    No MP tecnici (non rispondo nemmeno!), usa il forum.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.