Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219

    [C]Segmentation fault,agenda

    Salve a tutti,stavo da tempo sviluppando il progetto di un' agenda elettronica gentita dalla shell dei comandi,adesso ho scritto un codice che porto avanti da tempo che purtroppo è molto lungo da guardare,e ci sarebbero moltissime cose da dire.
    Compilato con code::blocks 10.05 su windows 7 non da ne avvisi ne errori,però crasha alla riga 568 ma non so capire il perchè.
    Siccome è lungo vi chiedo non di interpetare tutto il codice,ma solo di leggere quello relativo alla parte in cui crasha (riga 568),accessibile premendo prima 5 e poi 2 dalla shell.
    Ecco il link da pastebin:
    http://pastebin.com/dVxfw4zH
    Spero che qualcuno ci dia un' occhiata,non capisco perchè crashi senza ragione apparente.

  2. #2
    Il codice è abbastanza lungo, potresti dire per cortesia qual'è l'errore riscontrato? Oppure "crasha" automaticamente?

    In ogni caso come prima cosa quando si scrivono procedure così nidificate, è buona regola controllare l'utilizzo delle parentesi graffe, però è probabile anche che vi sia un errore nella condizione del ciclo while.

  3. #3
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    E' un segmentation fault,il debugger lo segnala cos' e segna anche la riga.
    Ho controllato e a me sembra che proprio in questa riga:

    codice:
    while(j<=ptr[i].data[6])
     {                        
    flag[j][(ptr[i].data[1]-oggi[1])+1]=true;
     j++;
      }
    Dia problemi,anche se ho provato a debuggare manualmente e ho visto che essendo il vettore la matrice di bool flag[25][14] sufficientemente grande da contenere gli indici j e (ptr[i].data[1]-oggi[1])+1,almeno apparentemente non ci sarebbe ragione per cui crahsa.
    L' errore in particolare è sigsev (segmentation fault),in modalità non debug l' applicazione smette di funzionare.Il debugger da anche lo stato dello stack,che non riesco a decifrare:
    codice:
    #0 779CE1FE	ntdll!LdrWx86FormatVirtualImage() (C:\Windows\system32\ntdll.dll:??)
    #1 00000000	0x00000000 in ??() (??:??)

  4. #4
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Che roba incredibile !!
    Ho modificato la matrice di bool aggiungendo una dimensione e tutto fila liscio.Cosi':

    codice:
    bool flag [26][14];
    Anche se ancora non capisco,gli elementi scanditi era 25 non 26

  5. #5
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Guardate,già che ci sto posto questo rompicapo che sto tentando di risolvere da giorni nell' agenda.
    Posto la porzione di codice così è più comprensibile.
    prima posto le variabili dichiarate e inizializzate precedentemente:
    codice:
    bool flag[26][14];
    typedef struct
    {
        char targa;
        int data [8];
        char *oggetto;
        char *testo;
    }nota;
    int num;
    nota *ptr;
    int oggi[4];
    Vi spiego cosa devono contenere queste variabili:
    ptr è un array di note,che ha come dimensione massima num (ptr[num-1]).
    ptr[i].data è un array di 8 elementi,data[0] contiene il mese,che va da 1 a 12,data[1] il giorno,data[2] l' ora,data[3] i minuti.
    data[4] contiene ancora un mese: in questo array di strutture,che leggo da file,ci sono già scritte correttamente delle note che contengono la data di inizio e la data di fine.
    Se queste note sono presenti nel range settimanale si attiva il bit corrispondente.
    oggi è un array di interi,anch'esso è un array contenente una data,e contiene la data del primo lunedì della settimana.
    In questo ciclo sto tentando disperatamente di scrivere sulla matrice di bool con questo criterio:
    Quando nel ciclo for trovo che una nota ha la data compresa nel range settimanale (deve innanzitutto avere lo stesso mese di oggi[0],poi avere il giorno (ptr[i].data[1] o ptr[i].data[5]) che va da oggi[1] a oggi[1]+7.
    Si deve attivare il bit corrispondente all' orario,ma ogni nota ha una targa.
    ptr[i].targa dice che tipo di nota è ('M','R','A','I').
    Successivamente passo la matrice di bit a una funzione (che ho verificato che si comporta correttamente) che a seconda di come gli passo l' array di bit di 14 elementi (&flag[i][0]) stampa M se nel posto giusto.
    Ho difficoltà a spiegare questo "nel posto giusto",vi posto un' immagine:

    http://img193.imageshack.us/img193/2108/prompti.png

    In pratica come vedete stampa tutti gli R nella prima colonna.però le altre colonne le lascia bianche (e sono sicuro che la funzione per stampare la tabella funziona correttamente).Ma se trova delle note che hanno un giorno superiore a lunedì,deve stampare anche nella altre colonne.Mentre 'M' e 'A' essendo note memo e anniversario non hanno l' ora ma vengono stampate all' inizio della tabella.
    Sembrerebbe che il criterio con cui assegno i bit è sbagliato:mi si attiva sempre solo il primo e il secondo bit (flag[i][0] e flag[i][1]) ma non so il perchè
    codice:
    for(i=0;i<num;i++)
            {
                if((ptr[i].data[0]==oggi[0]||ptr[i].data[4]==oggi[0])&&((ptr[i].data[1]>=oggi[1]&&ptr[i].data[1]<=oggi[1]+7)
                  ||(ptr[i].data[5]>=oggi[1]&&ptr[i].data[5]<=oggi[1]+7)))
                {
                    if(ptr[i].targa=='I')
                    {
                        flag[ptr[i].data[2]][(ptr[i].data[1]-oggi[1])*2]=true;
                        flag[ptr[i].data[6]][(ptr[i].data[5]-oggi[1])*2]=true;
                    }
                    else if(ptr[i].targa=='R')
                    {
                        int j=ptr[i].data[2];
                        while(j<=ptr[i].data[6])
                        {
                            flag[j][((ptr[i].data[1]-oggi[1])*2)+1]=true;
                            j++;
                        }
                    }
                    else if(ptr[i].targa=='M')
                      flag[0][(ptr[i].data[1]-oggi[1])]=true;
                    else
                      flag[0][(ptr[i].data[1]-oggi[1]+1)]=true;
                }
    Sto provando da giorni a farlo ma niente da fare,se quello che ho spiegato non vi è chiaro posso anche provare a rispiegare...non riesco proprio a fargli assegnare i bit correttamente

  6. #6
    Utente di HTML.it L'avatar di linoma
    Registrato dal
    Mar 2010
    Messaggi
    1,346
    ...rebuilding...

    da un primo fetch & execute personale i campi oggetto e testo hanno dei problemi. Direi che dovresti controllare i puntatori in generale.
    Per gli Spartani e Sparta usa spartan Il mio github

  7. #7
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    I campi oggetto e testo sono dei puntatori a stringhe,uso questa funzione per tirare su i caratteri da stdin o da file e allocare la memoria necessaria:
    codice:
    char* get_string(FILE *fp)
    {
        char *ptr;
        ptr=(char*)malloc(sizeof(char));
        if(ptr==NULL)
        {
            printf("Errore di lettura/inserimento dei dati,l' applicazione verra' chiusa\n");
            exit(1);
        }
        int i=1,ci;
        if(fp==stdin)
          fflush(fp);
        else
        {
            ci=fgetc(fp);
            if(ci!='\n')
              fseek(fp,-1,SEEK_CUR);
        }
        ptr[0]='\0';
        while(ci!=10&&ci!=EOF)
        {
            ptr=(char*)realloc(ptr,i*sizeof(char));
            if(ptr==NULL)
            {
                printf("Errore di lettura/inserimento dei dati,l' applicazione verra' chiusa\n");
                exit(1);
            }
            ci=fgetc(fp);
            if(ci!=10)
              ptr[i-1]=ci;
            else
              ptr[i-1]='\0';
            i++;
        }
        return ptr;
    }
    Anche se poi so che non è perfetta.
    I campi oggetto e testo non sono usati in questa porzione di codice.Il codice è chilometrico,in questa porzione il mio problema è assegnare i bit giusti,ma non ci riesco
    Se non avete capito il criterio con cui voglio assegnare i bit perchè mi sono spiegato male,chiedete pure.Non riesco proprio a dargli un senso,solo i bit con dimensione 0 e 1 si "avverano",gli altri non li tocco nemmeno e non capisco il perchè

  8. #8
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Ok,l' ho sistemato poi.
    Non era così facile come pensavo,bisognava mettere a 1 tutta la porzione dell' array che va da [(ptr[i].data[1]-oggi[1])*2] a [(ptr[i].data[5]-oggi[1])*2] nel caso la nota abbia la targa 'I' e nel caso abbia la targa 'R' aumentare di 1 la dimensione.Così mi attiva tutti i bit compresi tra l' ora di fine e di inizio.
    codice:
    for(i=0;i<num;i++)
            {
                if((ptr[i].data[0]==oggi[0]||ptr[i].data[4]==oggi[0])&&((ptr[i].data[1]>=oggi[1]&&ptr[i].data[1]<=oggi[1]+7)
                    ||(ptr[i].data[5]>=oggi[1]&&ptr[i].data[5]<=oggi[1]+7)))
                {
                    if(ptr[i].targa=='I')
                    {
                        int j=ptr[i].data[1];
                        while(j<ptr[i].data[5])
                        {
                            int k=(ptr[i].data[1]-oggi[1])*2;
                            while(k<=(ptr[i].data[5]-oggi[1])*2)
                            {
                                flag[j][k]=true;
                                k+=2;
                            }
                            j++;
                        }
                    }
                    else if(ptr[i].targa=='R')
                    {
                        int j=ptr[i].data[2];
                        while(j<=ptr[i].data[6])
                    {
                        int k=((ptr[i].data[1]-oggi[1])*2)+1;
                        while(k<=((ptr[i].data[5]-oggi[1])*2)+1)
                        {
                            flag[j][k]=true;
                            k+=2;
                        }
                        j++;
                    }
                }
                else if(ptr[i].targa=='M')
                    flag[0][(ptr[i].data[1]-oggi[1])]=true;
                else
                    flag[0][(ptr[i].data[1]-oggi[1]+1)]=true;
            }
        }

  9. #9
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    487

    bhe

    è normale che ti dava errore, o questoi lo scrivi così: bool flag[26][14];

    dando una dimensione costante definita in fase di compilazione e non più modificabile a run time...

    o così: bool ** flag, e allochi e deallochi dinqamicamente con malloc, free (meglio usare new e delete che sono C++)

    oppure puoi usare smart pointer della boost (C++)

    ma io preferisco in assoluto gli std::vector anchessi C++

  10. #10
    Utente bannato
    Registrato dal
    Oct 2010
    Messaggi
    1,219
    Quella matrice di bool è ancora identica e funziona.
    Dovrei passare anche io al c++ ma comunque non era questo l' errore.
    Non aveva le dimensioni giuste,scriveva sopra memoria non allocata.
    Ecco il codice dell' agenda che penso non cambierò mai più
    http://pastebin.com/S3am8qtk
    La dichiarazione della matrice sta alla riga 579,compilato con MinGW32 e funziona.

    P.S. Apprezzo se qualcuno mi sa dare consigli su come migliorare il codice (che è comunque funzionante),anche senza capire come funziona.Qualsiasi consiglio è apprezzato,grazie.

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.