Exosouler Δημοσ. 11 Ιανουαρίου 2012 Δημοσ. 11 Ιανουαρίου 2012 Παιδιά έχω φτιάξει ενα πρόγραμμα στην c και οταν του δινω ως είσοδο ν<=15 δουλεύει άψογα(έτσι πιστεύω) για ν απο 16 και άνω μου βγάζει segmentation fault.Δοκίμασα να κάνω αποσφαλμάτωση . Αλλοτε μου δείχνει οτι το προβλημα βρίσκεται στην γραμμή που η συναρτηση που έχω φτιάξει καλεί την ίδια > Program received signal SIGSEGV, Segmentation fault. 0x0804921a in rec (prm=0x804b098, prw=0x804b0e0, col=0x804b128, prefw=0x804b050, prefm=0x804b008, i=6, s=0, n=16) at rec.c:84 84 rec(prm,prw,col,prefw,prefm,i-1,1+col[i-1],n); Άλλοτε > Program received signal SIGSEGV, Segmentation fault. 0x08048d89 in rec (prm=0x804b098, prw=0x804b0e0, col=0x804b128, prefw=0x804b050, prefm=0x804b008, i=5, s=3, n=16) at rec.c:5 5 for (j=s;j<n;j++) { (gdb) p j Cannot access memory at address 0xbf62bffc το j είναι ακέραιος. Τι πρόβλημα μπορεί να υπάρχει παιδιά? >#include <stdio.h> #include <stdlib.h> #include <time.h> #include "ex3.h" int main (void) { int n,**prefw,**prefm,*prm,*prw,i,j,k,ab,flag,*col,l; long curtime; curtime=time(NULL); srand((unsigned int) curtime); printf("Please give the number of men and women\n"); scanf("%d",&n); if (n==0) { printf("There aren't any men and women to marry\n"); system("pause"); } prefm = malloc(n * sizeof(int *)); /* preferences for each man */ prefw = malloc(n * sizeof(int *)); /* preferences for each woman */ prm = malloc(n * sizeof(int )); /* woman whom each man has married */ prw = malloc(n * sizeof(int )); /* man whom each woman has married */ col = malloc((n+1)* sizeof(int )); /* point which column from prefm is woman whom each man has married */ /* col[n]: the number of solutions for part II of exercise 3 */ if (prefm==NULL || prefw==NULL || prm==NULL || prw==NULL || col==NULL) { printf("Sorry, cannot allocate memory\n"); return -1; } for (i=0;i<=n;i++) col[i]=0; for (i=0;i<n;i++) { *(prefm+i)=malloc(n * sizeof(int)); *(prefw+i)=malloc(n * sizeof(int)); if (*(prefm+i)==NULL || *(prefw+i)==NULL) { printf("Sorry, cannot allocate memory\n"); return -1; } } for (i=0;i<n;i++) { prm[i]=0; /* 0: point that the man i+1 is free */ printf("Please give the order of preferences for m%3.3d\n",i+1); for (j=0;j<n;j++) { do { prefm[i][j]=rand()%n+1; //scanf("%d",&prefm[i][j]); } while (cont(prefm,i,j,prefm[i][j])!=0); } } for (i=0;i<n;i++) { prw[i]=0; /* 0: point that the woman i+1 is free */ printf("Please give the order of preferences for w%3.3d\n",i+1); for (j=0;j<n;j++) { do { prefw[i][j]=rand()%n+1; // scanf("%d",&prefw[i][j]); } while (cont(prefw,i,j,prefw[i][j])!=0); } } printf("\n\n"); for (i=0;i<n;i++) { printf("m%3.3d order of preferences: ",i+1); for (j=0;j<n;j++) printf("w%3.3d ",prefm[i][j]); printf("\n"); } printf("\n"); for (i=0;i<n;i++) { printf("w%3.3d order of preferences: ",i+1); for (j=0;j<n;j++) printf("m%3.3d ",prefw[i][j]); printf("\n"); } printf("\n\n\nFinding the male optimal solution with the Gale-Shapley algorithm\n\n\n"); gshap(prm,prw,prefw,prefm,n); for (i=0;i<n;i++) prm[i]=prw[i]=0; printf("\n\n\nFinding all solutions with backtracking via recursion\n\n\n\n"); rec(prm,prw,col,prefw,prefm,0,0,n); system("pause"); } ex3.h: >int cont(int **,int,int,int); void rec (int *,int *,int *,int**,int **,int,int,int); int stmar (int *,int *,int**,int **,int,int,int); void gshap (int *,int *,int **,int**,int); rec.c: >int rec(int *prm,int *prw,int *col,int **prefw,int **prefm,int i ,int s,int n) { /* s: point which column from prefm is the first woman whom man i proposes */ //#include <stdio.h> int k,flag=0,j; while(i<n && col[n]!=-10) { for (j=s;j<n;j++) { printf("Trying to marry man %d to woman %d \n",i+1,prefm[i][j]); if (prw[prefm[i][j]-1]==0) { if (stmar(prm,prw,prefw,prefm,i,j,n)==0) { printf("Succeeded!!\n"); s=0; /* in order to try to marry the next man with the first woman of his preferences */ col[i]=j; prm[i]=prefm[i][j] ; prw[prefm[i][j]-1]=i+1 ; if (i==n-1) { /* if we marry and the last man */ col[n]++; /* increase by 1 the number of solutions */ printf("\nSolution %d: \n\n",col[n]); for (k=0;k<n;k++) { printf("m%3.3d - w%3.3d ",k+1,prm[k]); if ((k+1)%4==0 && k!=0) printf("\n"); } printf("\n\n"); if (n!=1) { prw[prm[i]-1]=0; prm[i]=0; } } else break; } else printf("Sorry, marriage is unstable\n"); } else printf("Sorry, woman%d is already married\n",prefm[i][j]); } if (prm[i]==0) { /* if man i is free */ prw[prm[i-1]-1]=0; /* free woman whom man i-1 has married */ prm[i-1]=0; /* free man i-1 */ for (k=0;k<=i-1;k++) if (col[k]!=n-1) flag=1; if (flag==0){ /* if each man before i has married the last woman of his preferences */ printf("\n\nFound %d Solution(s)\n",col[n]); flag=1; col[n]=-10; /* -10: random value which doesn't affect the program */ } else /* try to marry man i-1 */ rec(prm,prw,col,prefw,prefm,i-1,1+col[i-1],n); } i++; } } stmar.c: >int stmar (int *prm,int *prw,int **prefw,int **prefm,int i,int j,int n) { int k,flag1,p,flag2,ke,kr; for (k=1;k<=i;k++) { flag1=0; for(p=0;p<n;p++) { if (prefw[prm[k-1]-1][p]== i+1) /* if woman of man k prefers man i+1 more than her man */ flag1++; else if (prefw[prm[k-1]-1][p]== k) /* if woman of man k prefers her man more than man i */ break; } for(p=0;p<n;p++) { if (prefm[i][p]==prm[k-1]) /*if man i prefers woman of man k more than his woman */ flag1++; else if (prefm[i][p] == prefm[i][j]) /*if man i prefers his woman more than woman of man k */ break; } if (flag1==2 ) /* if there is a unstable marriage */ break; } for (k=1;k<=i;k++) { flag2=0; for(p=0;p<n;p++) { if (prefm[k-1][p]==prefm[i][j]) /*if man k prefers woman of man i more than his woman */ flag2++; else if (prefm[k-1][p]==prm[k-1]) /*if man k prefers his woman more than woman of man k */ break; } for(p=0;p<n;p++) { if (prefw[prefm[i][j]-1][p]==k) /*if woman of man i prefers man k more than her man */ flag2++; else if (prefw[prefm[i][j]-1][p]==i+1) /*if woman of man i prefers her man more than man k */ break; } if (flag2==2) /* if there is a unstable marriage */ break; } if (flag1==2 || flag2==2) return 1; else return 0; } ότι δεν έχω στείλει δεν χρειάζεται.
koslibpro Δημοσ. 11 Ιανουαρίου 2012 Δημοσ. 11 Ιανουαρίου 2012 στη θεση αυτου > for (j=s;j<n;j++) δοκιμασε > for (j=s;j<=n;j++) γιατι νομζω πως αυτο φταιει.
migf1 Δημοσ. 11 Ιανουαρίου 2012 Δημοσ. 11 Ιανουαρίου 2012 Από το output του gdb, στο οποίο έχεις κάνει backtrace μετά από το segmentation fault, το πιθανότερο είναι κάποιο από τα ορίσματα δείκτες της rec να είναι invalid όταν καλείς την συνάρτηση. Πιθανότατα το *col. Δεν έχω κουράγιο τώρα να δω όλον αυτόν τον κώδικα, δοκίμασε όμως να βάλεις ένα breakpoint ακριβώς πριν την κλήση της rec, και βάλε τον gdb να σου δείξει όλα τα ορίσματα που ετοιμάζεσαι να τις περάσεις... πιθανότατα κάποιο από αυτά θα είναι invalid... μάλλον το col. Π.χ. μήπως το col[i-1] είναι με i == 0 οπότε γίνεται col[0-1] ;
Exosouler Δημοσ. 11 Ιανουαρίου 2012 Μέλος Δημοσ. 11 Ιανουαρίου 2012 δεν είναι αυτό το πρόβλημα γιατι το i είναι μεγαλύτερο του 1 όταν μου βγάζει πρόβλημα,μπορείς να μου εξηγήσεις πως μπορώ να βάλω το breakpoint?
migf1 Δημοσ. 12 Ιανουαρίου 2012 Δημοσ. 12 Ιανουαρίου 2012 μέσα στον gdb πριν κάνεις run για να τρέξει το πρόγραμμά σου, γράφεις π.χ.: b 123 όπου 123 η γραμμή του κώδικα που θες να μπει το breakpoint. Όταν βάλεις όσα breakpoints θέλεις, κάνεις: run για να ξεκινήσει το πρόγραμμά σου... θα σταματήσει στο 1ο breakpoint. με: p variable σου τυπώνει την τιμή της variable... με disp variable σου τυπώνει την τιμή της variable και στην τυπώνει συνέχεια μετά από κάθε step, μέχρι να την κάνεις undisp (display & undisplay σημαίνουν αυτά). για να προχωρήσεις μια γραμμή πατάς: n για να μπεις μέσα σε συνάρτηση, αντί για n πατάς s (next & step σημαίνουν αυτά). ΥΓ. Πατώντας σκέτο ENTER εφαρμόζει την αμέσως προηγούμενη εντολή που του έχεις δώσει.
Exosouler Δημοσ. 12 Ιανουαρίου 2012 Μέλος Δημοσ. 12 Ιανουαρίου 2012 αν η γραμμη που θέλω να βαλω το breakpoint είναι σε μια συνάρτηση και όχι στην main τι βάζω?
migf1 Δημοσ. 12 Ιανουαρίου 2012 Δημοσ. 12 Ιανουαρίου 2012 Δεν έχει σημασία που είναι, το νούμερο της γραμμής του κώδικα βάζεις... σε τι περιβάλλον προγραμματίζεις;
migf1 Δημοσ. 12 Ιανουαρίου 2012 Δημοσ. 12 Ιανουαρίου 2012 man gdb ή ακόμα καλύτερα.. info gdb Αν χρησιμοποιείς emacs είσαι τυχερός, γιατί έχει ειδικό mode για τον gdb... χωρίζεις την οθόνη σε 2 παράθυρα, στο 1 βλέπεις τον κώδικα και στο άλλο τα του gdb... γενικώς χρησιμοποιείς το παράθυρο του κώδικα για να βλέπεις την ροή του προγράμματος, να βάζεις breakpoints, κλπ. Άσχετα με τα παραπάνω, δες κι αυτό το tutorial: http://www.unknownro...tut/gdbtoc.html ΥΓ. Έχω την εντύπωση πως ο Dev-C++ έχει ενσωματωμένο γραφικό περιβάλλον για τον gdb. Κι αυτό είναι καλό tutorial: http://www.delorie.c...db/gdb_toc.html Είναι από την DOS (16μπιτη) υλοποίηση του GCC, την DJGPP αλλά είναι πολύ καλό tutorial (σε περίπτωση δηλαδή που σε χαλάνε τα man και info στο Unix).
Exosouler Δημοσ. 12 Ιανουαρίου 2012 Μέλος Δημοσ. 12 Ιανουαρίου 2012 Breakpoint 4, rec (prm=0x804b098, prw=0x804b0e0, col=0x804b128, prefw=0x804b050, prefm=0x804b008, i=7, s=0, n=16) at rec.c:50 50 rec(prm,prw,col,prefw,prefm,i-1,1+col[i-1],n); (gdb) p 1+col[i-1] $1 = 2 (gdb) p i $2 = 7 (gdb)
migf1 Δημοσ. 12 Ιανουαρίου 2012 Δημοσ. 12 Ιανουαρίου 2012 Δούλεψέ το μέχρι να βρεις το λάθος (βάλε να σου δείξει τις τιμές όλων των ορισμάτων της rec)... μπορείς αντί για πριν να βάλεις το breakpoint μέσα στην rec, αμέσως πριν αρχίσει να εκτελεί το for. Επίσης, άμα το τρέξεις χωρίς breakpoints και σου βαρέσει seg-fault, γράψε bt (που σημαίνει backtrace) και θα σου δείξει τη σειρά των συναρτήσεων που κλήθηκαν μέχρι το σκάσιμο.
Exosouler Δημοσ. 12 Ιανουαρίου 2012 Μέλος Δημοσ. 12 Ιανουαρίου 2012 πώς γίνετε να μου δείξει τις τιμές του πίνακα?(εκτος απο το να γράφω π και κα8ε θέση του πίνακα ξεχωριστά) Αφου μου δείξει την σειρά τι πρέπεει να ελένξω? Γιατί κάποιες φορές μου δείχνει οτι βρίσκεται αλλού το πρόβλημα? > Program received signal SIGSEGV, Segmentation fault. 0x080490fa in rec (prm=0x804b098, prw=0x804b0e0, col=0x804b128, prefw=0x804b050, prefm=0x804b008, i=6, s=5, n=16) at rec.c:9 9 if (stmar(prm,prw,prefw,prefm,i,j,n)==0) {
migf1 Δημοσ. 12 Ιανουαρίου 2012 Δημοσ. 12 Ιανουαρίου 2012 Φίλε μου σου έδωσα και links και hints για να βρεις ότι θέλεις. Ο gdb μόνο καφέ δεν ψήνει... αν ήταν να το κάνω εγώ debug το πρόγραμμά σου θα το έκανα από την αρχή αντί να γράφω μηνύματα στο φόρουμ
Προτεινόμενες αναρτήσεις
Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε
Πρέπει να είστε μέλος για να αφήσετε σχόλιο
Δημιουργία λογαριασμού
Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!
Δημιουργία νέου λογαριασμούΣύνδεση
Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.
Συνδεθείτε τώρα