PDA

Visualizza la versione completa : [C] Errore "Segmentation Fault" in agenda elettronica


ramy89
28-12-2010, 19:35
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.

MdE2005
28-12-2010, 19:37
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.

ramy89
28-12-2010, 19:46
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:



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:


#0 779CE1FE ntdll!LdrWx86FormatVirtualImage() (C:\Windows\system32\ntdll.dll:??)
#1 00000000 0x00000000 in ??() (??:??)

:bhò:

ramy89
28-12-2010, 20:59
Che roba incredibile !!
Ho modificato la matrice di bool aggiungendo una dimensione e tutto fila liscio.Cosi':



bool flag [26][14];


Anche se ancora non capisco,gli elementi scanditi era 25 non 26 :dottò:

ramy89
30-12-2010, 16:24
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:


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.th.png
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è :dhò:


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 :confused:

linoma
30-12-2010, 16:27
...rebuilding...

da un primo fetch & execute personale :) i campi oggetto e testo hanno dei problemi. Direi che dovresti controllare i puntatori in generale.

ramy89
30-12-2010, 18:17
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:


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è :confused:

ramy89
31-12-2010, 13:46
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.


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;
}
}

kirakira93
03-01-2011, 18:36
è 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++

ramy89
03-01-2011, 19:08
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.

Loading