Thread: Unstopping While loop

  1. #1
    Registered User
    Join Date
    Oct 2012
    Posts
    71

    Unstopping While loop

    Hi all,

    In my function, the while loop is not terminating when it should so when the code within that while loop is called, the program stops prematurely because of a Segmentation fault.

    This program is used to create directory structures tree of depth d and breadth b which come from argv and works for the 1st and 2nd iteration of the outside for loop but it does not go to the 3rd iteration because it continues through the while loop of the 2nd iteration.

    P.S. what's also strange is that the program works fine for smaller depth and breadth so could this be a problem with my system's memory allocation possibly?

    Declarations and main function..
    Code:
    #include <stdio.h>
    #include <malloc.h>
    #include <string.h>
    #include <stdlib.h>
    #include <math.h>
    
    #define MAXD 10            /* 3 <= depth < MAXD  */
    #define MAXB 10            /* 3 <= breadth < MAXB  */
    
    void create_dir_tree();
    void traverse_dir_tree();
    int find_total_no_dirs();
    int find_dir();
    
    struct dir {
      char *path;           /* path to get to this dir, not including this */
      char *name;           /* current dir name */
      int d;           /* 3 <= depth level < MAXD */
      /* the init_d is depth 0, its immediate subdirs are depth 1, etc. */
      int b;           /* 3 <= breadth or number of sub dirs < MAXB */
      struct dir *up;       /* points to the parent */
      struct dir **down; /* points to the sub dirs of this dir. Note the TWO *'s */
      struct dir *left;       /* left sibling dir, use circular link */
      struct dir *right;       /* right sibling dir, use circular link */
    };
    
    int main(int argc, char **argv) {
      struct dir *hp;
      int b,d,n,flag;
      char *init_d,tst_dir[100];
    
      if (argc < 4) {
        printf("usage: hw3 root_d d b\n");
        return 1;
      }
    
      argv++;            /* skip the command itself */
      init_d = *(argv++);
      d = atoi(*argv++);
      b = atoi(*argv++);
    
      create_dir_tree(&hp,init_d,d,b);
      if ((flag = find_dir(hp,tst_dir)))
        printf("dir %s found\n",tst_dir);
      else
        printf("no dir %s found\n",tst_dir);
      return 0;
    }
    problem function
    Code:
    /* create directories breadth first */
    void create_dir_tree(struct dir **hp,char *name,int d, int b) {
    
      printf("create_dir_tree init_d=%s depth=%d breadth=%d\n",name,d,b);
      /* fill in here */
      struct dir *cp;
      struct dir *tmp;
      struct dir **newopen=malloc(sizeof(struct dir*));
      struct dir **open;
      struct dir **closed=malloc(sizeof(struct dir*));
      int count = 0;
      int ccounter=0;
      int counter = 0;
      char *buffer=malloc(3);
      char *buff;
      if(!buffer||!buff)
        return;
      cp=(*hp);
      cp=malloc(sizeof(struct dir));
     
      cp->name = name;
      cp->path = "\0";
      cp->d = 0;
      cp->b = 1;
      cp->up = NULL;
      cp->left = NULL;
      cp->right = NULL;
    
      *newopen= cp;
      int i;
      for(i = 0; i < d ; i++){
        
        open=newopen;
        printf("First element of newopen: %s%s\n",(*newopen)->path,(*newopen)->name);
        printf("Malloc %d^%d or %f structs for newopen\n", b,i+1,pow(b,i+1));
        newopen=malloc(pow(b,i+1)*sizeof(struct dir*));
        count = 0;
        counter = 0;
        closed = realloc(closed, ccounter * sizeof(struct dir*)+1);
    
        while(open[0]){           //bug during i=1 after the while loop should be done 
                                        //=> suppose to fail to go to i=2 but continues here anyway making any reference to open[0] or *open causes segment fault
          printf("Start of while loop\n");
          printf("Expanding %s%s\n",(*open)->path,(*open)->name);
          cp = *open;                      
          printf("passed the error\n");
          cp->down=malloc(b * sizeof(struct dir*));
          count=counter;
          int j;
          for(j = 0; j < b; j++,counter++){
        tmp = malloc(sizeof(struct dir));
        buff=malloc(3);
        newopen[j+count]=tmp;
        tmp->up=cp;
        tmp->path=realloc(tmp->path,strlen(tmp->up->path)+strlen(tmp->up->name)+1);
        strcpy(tmp->path,tmp->up->path);
        strcat(tmp->path,tmp->up->name);
        tmp->name=malloc(4);
        *buff='/';
        sprintf(buffer,"%d", j);        
        strcat(buff,buffer);
            tmp->name=realloc(tmp->name,strlen(tmp->name)+strlen(buff)+1);
        strcat(tmp->name,buff);
        printf("Creating Directory: %s%s\n",tmp->path,tmp->name);
    
        cp->down[j]=tmp;
        if(j==(b-1)){
          cp->down[j]->right=cp->down[0];
          cp->down[0]->left=cp->down[j];
        }
        else if (j>0){
          cp->down[j-1]->right=cp->down[j] ;
    
        }
       
          }
          printf("Just expanded: %s%s and appending to closed\n",(*open)->path,(*open)->name);
          closed[ccounter++]=*open;
          open++;
          printf("%s\n","End of While Loop");
        }
      }
    }

  2. #2
    Registered User ch4's Avatar
    Join Date
    Jan 2007
    Posts
    152
    1. You should name your variables in more explainable way. (b,d = ???)
    2. one is pointer to pointer. one[0] is pointing to pointer. If one[0] isn't null (0) then has as value a memory address that's always no zero. Accessing addresses out of your program causes seg faults.
    Last edited by ch4; 10-20-2012 at 02:57 PM.

  3. #3
    Registered User
    Join Date
    Oct 2012
    Posts
    71
    b refers to breadth of the tree and d refers to the depth of the tree.
    Also thanks for your reply! I found that newopen was short a bit of memory so it wasn't really NULL terminated (i think). After adding +1 to the malloc, this bug went away and the while loop's working nicely.

    After this though, another bug came up with invalid next size for

    closed = realloc(closed, ccounter * sizeof(struct dir*)+2);

    I just added the +2 there to see if that would fix it but no luck.

  4. #4
    Registered User
    Join Date
    Oct 2012
    Posts
    71
    Ok dumb logic mistake on my part. I wasn't suppose to use ccounter to decide how much to realloc for closed, fixed that and it is working fine.

    Thanks for the help ch4!

  5. #5
    Registered User
    Join Date
    Oct 2012
    Posts
    71
    I ran this code in valguard and it says I've definitely lost a heck of a lot of memory, but I don't understand why. I don't free any pointers and each node should be connected to its parent node all the way up to the head pointer. As long as there is a pointer pointing to the memory, doesn't the heap return all of that memory when the program finishes running?

  6. #6
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Quote Originally Posted by workisnotfun View Post
    I ran this code in valguard and it says I've definitely lost a heck of a lot of memory, but I don't understand why. I don't free any pointers and each node should be connected to its parent node all the way up to the head pointer. As long as there is a pointer pointing to the memory, doesn't the heap return all of that memory when the program finishes running?
    Yes, and it will. But why are you running Valgrind if you know that you are never calling free.

  7. #7
    Registered User
    Join Date
    Oct 2012
    Posts
    71
    I get a relloc(): invalid pointer for depths > 3 and breadths > 3, but the function successfully creates the a tree up to depth and breadth of 3 so I thought Valgrind might help.
    Last edited by workisnotfun; 10-20-2012 at 05:35 PM.

  8. #8
    Registered User
    Join Date
    Jan 2009
    Posts
    1,485
    Ah, ok I see.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 12-26-2011, 07:36 PM
  2. change var inside loop and run loop again
    By d387420489 in forum C Programming
    Replies: 5
    Last Post: 07-29-2011, 01:19 AM
  3. Replies: 23
    Last Post: 04-05-2011, 03:40 PM
  4. for loop ignoring scanf inside loop
    By xIcyx in forum C Programming
    Replies: 2
    Last Post: 04-17-2007, 01:46 AM
  5. Replies: 3
    Last Post: 03-14-2006, 11:09 AM