Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Παιδιά έχω φτιάξει ενα πρόγραμμα στην 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;
}


ότι δεν έχω στείλει δεν χρειάζεται.

  • Απαντ. 46
  • Δημ.
  • Τελ. απάντηση

Συχνή συμμετοχή στο θέμα

Συχνή συμμετοχή στο θέμα

Δημοσ.

Από το output του gdb, στο οποίο έχεις κάνει backtrace μετά από το segmentation fault, το πιθανότερο είναι κάποιο από τα ορίσματα δείκτες της rec να είναι invalid όταν καλείς την συνάρτηση. Πιθανότατα το *col.

 

Δεν έχω κουράγιο τώρα να δω όλον αυτόν τον κώδικα, δοκίμασε όμως να βάλεις ένα breakpoint ακριβώς πριν την κλήση της rec, και βάλε τον gdb να σου δείξει όλα τα ορίσματα που ετοιμάζεσαι να τις περάσεις... πιθανότατα κάποιο από αυτά θα είναι invalid... μάλλον το col.

 

Π.χ. μήπως το col[i-1] είναι με i == 0 οπότε γίνεται col[0-1] ;

Δημοσ.

δεν είναι αυτό το πρόβλημα γιατι το i είναι μεγαλύτερο του 1 όταν μου βγάζει πρόβλημα,μπορείς να μου εξηγήσεις πως μπορώ να βάλω το breakpoint?

Δημοσ.

μέσα στον 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 εφαρμόζει την αμέσως προηγούμενη εντολή που του έχεις δώσει.

Δημοσ.

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).

Δημοσ.

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)

Δημοσ.

Δούλεψέ το μέχρι να βρεις το λάθος (βάλε να σου δείξει τις τιμές όλων των ορισμάτων της rec)... μπορείς αντί για πριν να βάλεις το breakpoint μέσα στην rec, αμέσως πριν αρχίσει να εκτελεί το for.

 

Επίσης, άμα το τρέξεις χωρίς breakpoints και σου βαρέσει seg-fault, γράψε bt (που σημαίνει backtrace) και θα σου δείξει τη σειρά των συναρτήσεων που κλήθηκαν μέχρι το σκάσιμο.

Δημοσ.

πώς γίνετε να μου δείξει τις τιμές του πίνακα?(εκτος απο το να γράφω π και κα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) {             

Δημοσ.

Φίλε μου σου έδωσα και links και hints για να βρεις ότι θέλεις. Ο gdb μόνο καφέ δεν ψήνει... αν ήταν να το κάνω εγώ debug το πρόγραμμά σου θα το έκανα από την αρχή αντί να γράφω μηνύματα στο φόρουμ ;)

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα

  • Δημιουργία νέου...