Thread: Pointer to Pointer manipulation issue

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

    Unhappy Pointer to Pointer manipulation issue

    I am creating directory structure objects for a tree. The problem I am working on is the create directory tree function. The first, second, and third loop work but when it goes through the while loop for the second time and the nested for loop a second time, a segmentation fault occurs. Am I using the **variable incorrectly?

    My friend once told me that pointers were similar to arrays and I also thought that **variables could be used similar to the argv parameter.

    If this is idea isn't right or I am just working with the variable incorrectly, please let me know! Thanks.

    Code:
    #include <stdio.h>
    #include <malloc.h>
    #include <string.h>
    #include <stdlib.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);
      traverse_dir_tree(hp);
      n = find_total_no_dirs(hp);
      strcpy(tst_dir,"root_d/a/bb/ccc/dddd");
      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;
    }
    
    /* 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);
      
      (*hp)=malloc(sizeof(struct dir));
        
      (*hp)->path = NULL;
      (*hp)->name = name;
      (*hp)->d = 0;
      (*hp)->b = 1;
      (*hp)->up = NULL;
      (*hp)->left=NULL;
      (*hp)->right=NULL;   
      
      struct dir **open;
      struct dir *cp;
      struct dir **tp;
      open=hp;
      int i;
    
      for(i=0;i<d;i++){
        while(open){
          tp=open;
          int j;
          cp=*open;
          for(j=0;j<b;j++){
        printf("depth=%d breadth=%d\n",i,j);
        struct dir *tmp=malloc(sizeof(struct dir));
        tp++;
        tp=&tmp;
        tmp->d=i;
        tmp->b=j;
        if(j==0){
          cp->down=&tmp;
        }
        else{
          (*(cp->down))->right=tmp;
          cp->down=&tmp;
          free(tmp);
        }
          }
          printf("made it out depth=%d breadth=%d\n",i,j);
          open++;
        }
        }
    }

  2. #2
    Registered User
    Join Date
    Mar 2011
    Posts
    546
    Code:
    open++;
    you are incrementing a pointer to a single instance. when you increment it, it points to some random location

  3. #3
    Registered User
    Join Date
    Oct 2012
    Posts
    71
    Quote Originally Posted by dmh2000 View Post
    Code:
    open++;
    you are incrementing a pointer to a single instance. when you increment it, it points to some random location
    i have tp=open right after the while(open) and I do tp++, then tp=&tmp;, doesn't open++, go to the next address which was pre-determined by tp++?

    The problem, I think, is how I am trying to use the **tp and **open as arrays. If I could just get the syntax right, I think the algorithm should work.
    Last edited by workisnotfun; 10-16-2012 at 10:46 AM.

  4. #4
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by workisnotfun View Post
    My friend once told me that pointers were similar to arrays and I also thought that **variables could be used similar to the argv parameter.
    Pointers are not arrays. They can be treated as equivalent in some circumstances but not in others.

    If a pointer to a single instance is incremented, dereferencing it gives undefined behaviour. It doesn't magically cause dynamically allocated memory to grow. As dmh said, that may explain your problem.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  5. #5
    Registered User
    Join Date
    Oct 2012
    Posts
    71
    In this case, I want 'open' to act as a pointer to pointers similar to argv and 'tp' to act as adding onto 'open' in a way similar to adding on to the end of an array. Is there a way I could do this while leaving open and tp as a struct dir ** type or is the only way to do this: make open struct dir* open[ ] with an initialized amount of space? If possible, I'd like to go the first way and learn more about pointers.

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Quote Originally Posted by workisnotfun View Post
    In this case, I want 'open' to act as a pointer to pointers similar to argv and 'tp' to act as adding onto 'open' in a way similar to adding on to the end of an array.
    The only reason that works for argv is that the argv array is already allocated. If you increment argv (or an equivalent pointer) too far, it falls off the end of the array just as your code is doing.
    Quote Originally Posted by workisnotfun View Post
    Is there a way I could do this while leaving open and tp as a struct dir ** type or is the only way to do this: make open struct dir* open[ ] with an initialized amount of space? If possible, I'd like to go the first way and learn more about pointers.
    I repeat. Pointer operations are not the way to make arrays grow. Making two pointers equivalent, and then incrementing one of them, does not reallocate anything. It simply means the two pointers have different values. If one of the pointers happens to point past the end of a array (dynamically allocated or not) the array is not affected. The pointer (pointing past the end) simply points to a non-existent object.

    I suggest you worry about understanding pointers FIRST, before trying to resize arrays. It is possible to resize dynamically allocated arrays but, if you don't understand what operations you use on pointers actually do, you will keep making the same sorts of mistakes and confuse yourself even further.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Help needed with string pointer manipulation
    By livin in forum C Programming
    Replies: 2
    Last Post: 02-05-2012, 12:57 PM
  2. pointer to pointer manipulation
    By stanlvw in forum C++ Programming
    Replies: 3
    Last Post: 06-03-2008, 02:34 PM
  3. Pointer Manipulation with strcat()
    By radiohead in forum C Programming
    Replies: 3
    Last Post: 03-03-2006, 07:17 AM
  4. Pointer manipulation
    By shaun84 in forum C Programming
    Replies: 3
    Last Post: 10-23-2005, 03:27 PM
  5. Question regarding pointer manipulation
    By samadhi in forum C Programming
    Replies: 4
    Last Post: 04-05-2005, 02:57 AM