Thread: Multiple segmentation faults in permutation generating program

  1. #1
    Registered User
    Join Date
    Aug 2007
    Posts
    6

    Multiple segmentation faults in permutation generating program

    My problem is the following: i'm trying to write a program, that writes out all the permutations of a string, that is given to the program as 1st argument. Sadly multiple part of the code give segfault error (if i comment part of the code, another part gives that error). I'm using gcc under Unix (gentoo).

    I traced back the segfaults with the Gnu debugger. I know what part(s) cause the error(s), but i don't know why. I commented the place of "bad code".

    Here's the program:

    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main(argc,argv)
     int argc;
     char *argv[];
     {
     int i=0,l;     
     char s[20],sk[20];
     sk[0]='\0';
    
    
     while (*++argv[i] != '\0') /* according to the debugger this while loop causes segfault */
        {
        s[i]=*++argv[i];
        i++;
        }
    
     s[i]='\0';
     i=0;
     l=strlen(s);
     printf(" %s ",s);
     permutal(sk,s,i,l);
     }
    
     permutal(sk,s,i,l)
      char sk[20],s[20];
      int i,l;
      {
      int j=0;
      char ideiglenes,s2[20];
    
      while (s[j] != '\0') /*this loop causes segfault too*/
       {
       s2[j]=s[j];
       j++;
       }
    
       printf(" %s ",s);
    
       s2[j]='\0';
      
      for (j=i;j<l && i<l;j++) /* And finally this for loop causes segfault too /*
       {
       sk[i]=s[j];
       sk[i+1]='\0';
       ideiglenes=s[i];
       s2[i]=s2[j];
       s2[j]=ideiglenes;
       if (i != l-1)
        permutal(sk,&s2[i],i+1,l);
        if (l == strlen(sk))
         printf("%s\n",sk);
       }
      }
    Can someone tell me why do i receive segmentation faults ?

  2. #2
    Registered User
    Join Date
    Jan 2007
    Posts
    330
    what book are you using to learn C? The function parameter style you're using was obsoleted in 1989......

    For the rest, debug your code, see what input you're giving it and what the different statements do. You'll find the bug(s)

  3. #3
    Registered User OnionKnight's Avatar
    Join Date
    Jan 2005
    Posts
    555
    while (*++argv[i] != '\0')
    Umm, why are you incrementing each char pointer in argv, and why do you check if the second character is '\0' as loop conditional? I am not even sure if you're even allowed to do the former. Your loop only ends if it encounters a single character command line parameter, so it probably segfaults when you don't provide any.

  4. #4
    Registered User
    Join Date
    Aug 2007
    Posts
    6
    What book i use? "The C programming Language"
    Know any better? Is "The C book" better for example?

    Umm, why are you incrementing each char pointer in argv, and why do you check if the second character is '\0' as loop conditional? I am not even sure if you're even allowed to do the former. Your loop only ends if it encounters a single character command line parameter, so it probably segfaults when you don't provide any.
    Well, i was thinking *++argv means that im looking at the first argument of a program, and *++argv[i] is the i-th character of that.
    Would *(argv+1)[i] be better?

    The purpose of that loop would be to copy the first argument into the s variable.


    I'm trying to figure this out since weeks. I debugged, tried to use different inputs, but always got the same error.

  5. #5
    Registered User
    Join Date
    Mar 2004
    Posts
    536
    Quote Originally Posted by kanesoban View Post
    What book i use? "The C programming Language"
    Know any better?
    The second edition.
    Quote Originally Posted by kanesoban View Post
    The purpose of that loop would be to copy the first argument into the s variable.
    argv is the name of an array of pointers.

    argv[0] is a pointer to the program name.

    The first argument is pointed to by argv[1] (if there were any arguments).

    First of all: make sure that argc is not less than 2.

    Then: You could make a loop that uses argv[1], but since you are already using functions from <string.h>, why not just use strcpy()?
    Code:
    .
    .
    .
        if (argc < 2) {
            printf("Usage: &#37;s stringtopermute\n", argv[0]);
            return 0;
        }
        strcpy(s, argv[1]);
        printf("s: <%s>\n", s);
    .
    .
    .
    Now, as a learning process, if you want to copy the argument a char at a time, you could do it several ways.

    With the kind of notation you were using and with no <string.h> functions, you could use a loop like the following:
    Code:
        /* argv[1] is a pointer whose value is the first char of the argument  */
        for (i = 0; *argv[1] != '\0'; i++) {
            s[i] = *argv[1]++; /* increment the pointer after getting the char */
        }
        s[i] = '\0';
        printf("string length = %d\n", i);
    Actually there should be some tests to make sure that the argument is not too big to store in your array.

    Since you are going to copy the argument to an array of 20 chars:

    If you are going to use strcpy(), first use strlen() on argv[1] to make sure it is no longer than 19 chars (to leave room for the terminating zero byte).

    If you are going to use the loop, put in a condition that makes sure that i can never be bigger than 19 (since you store the terminating zero in s[i]).



    D
    Last edited by Dave Evans; 08-14-2007 at 09:17 AM.

  6. #6
    Registered User
    Join Date
    Aug 2007
    Posts
    6
    Thanks. I modified the two while loops according to your guidance, and now there are no segfaults.
    True, the program still does nothing (it dosent write out anything, it just ends). I guess this is an improvement.



    Okay, i managed to fix my code, so it now writes out all permutations. If anyone needs it:

    Code:
    #include <stdio.h>
    #include <string.h>
    
    int main(argc,argv)
     int argc;
     char *argv[];
     {
     int l;
     char sk[20];
     sk[0]='\0';
     if (l <= 19)
      permutal(sk,argv[1],0,strlen(argv[1]),strlen(argv[1]));
     }
    
    
    permutal(sk,s,i,l,l2)
      char sk[20],s[20];
      int i,l,l2;
      {
      int j=0;
      char ideiglenes,s2[20];
      strcpy(s2,s);
      for (j=0;j<l;j++)
       {
       sk[i]=s2[j];
       sk[i+1]='\0';
    
       ideiglenes=s2[0];
       s2[0]=s2[j];
       s2[j]=ideiglenes;
    
       if (i != l2)
        permutal(sk,&s2[1],i+1,l-1,l2);
    
       if (l == 1)
        {
        printf("&#37;s\n",sk);
        }
    
       ideiglenes=s2[0];
       s2[0]=s2[j];
       s2[j]=ideiglenes;
    
       }
      }
    Last edited by kanesoban; 08-15-2007 at 08:45 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 18
    Last Post: 12-05-2003, 12:06 PM
  2. Multiple Windows, One Program?
    By skyruler54 in forum C++ Programming
    Replies: 3
    Last Post: 10-12-2002, 08:29 PM
  3. multiple runs of a program
    By unregistered in forum Linux Programming
    Replies: 5
    Last Post: 03-15-2002, 07:18 AM
  4. Disabling multiple instances of a program
    By xds4lx in forum Windows Programming
    Replies: 6
    Last Post: 03-06-2002, 02:21 AM
  5. program that uses multiple funtions
    By mike in forum C++ Programming
    Replies: 5
    Last Post: 02-09-2002, 08:44 AM