Thread: Quick double pointer question

  1. #1
    Registered User
    Join Date
    Mar 2013
    Posts
    16

    Quick double pointer question

    When I try to assign strings to a double pointer, it only prints out the last string when I try to print everything out, and then it segfaults.
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <assert.h>
    main(){  
      char **test = calloc(3,sizeof(char));
      *test = "Test";
      (*test)++;
      *test = "This";
      (*test)++;
      *test = "Code";
      int a;
      for(a=0;a<3;a++){
          printf("%s\n",test[a]);
      }
      for(a=0;a<3;a++){
          free(test[a]);
      }
      free(test);
    return 0;
    }
    Am I assigning something the wrong way?
    Also, I am trying to avoid using array notation in order to practice, at least for the assigning of the strings.
    Last edited by Otto45; 05-02-2013 at 09:43 PM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    This is wrong:
    Code:
    char **test = calloc(3,sizeof(char));
    You probably wanted to allocate space for 3 pointers to char, so it should have been:
    Code:
    char **test = calloc(3, sizeof(char*));
    but you can avoid such mistakes to begin with by writing:
    Code:
    char **test = calloc(3, sizeof(*test));
    This is wrong:
    Code:
      for(a=0;a<3;a++){
          free(test[a]);
      }
    You did not use malloc/calloc to allocate, so you should not use free.

    Oh, and this is not good practice:
    Code:
    *test = "Test";
    "Test" will be converted to a const char*, hence you are assigning a const char* to a char*. This risks modifying the string literal through the pointer to non-const char, resulting in undefined behaviour.

    Also, where are your header inclusions?

    Oh, and another thing: why are you incrementing the char* instead of the char** when you want to traverse to the next char*?

    Besides this, main should be explicitly declared as returning an int.
    Last edited by laserlight; 05-02-2013 at 09:42 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Registered User
    Join Date
    Mar 2013
    Posts
    16
    I added the headers to my code above, I had them in mine but I forgot to put them above. Also, I tried your suggestions and I still have the same issue

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    You probably missed my last edit:
    Quote Originally Posted by laserlight
    Oh, and another thing: why are you incrementing the char* instead of the char** when you want to traverse to the next char*?

    Besides this, main should be explicitly declared as returning an int.
    The second one shouldn't be an actual problem here, though it is still wrong in modern C.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    Quote Originally Posted by Otto45 View Post
    I added the headers to my code above, I had them in mine but I forgot to put them above. Also, I tried your suggestions and I still have the same issue
    You're also not actually traversing the three pointers in your array of pointers, you're incrementing the value of the first of the three pointers, and never touching the second or third pointer.
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

  6. #6
    Registered User
    Join Date
    Mar 2013
    Posts
    16
    I fixed both of those things in your edit, and it is still doing the same thing

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    What is your current code?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    Registered User
    Join Date
    Mar 2013
    Posts
    16
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <assert.h>
    int main(){
      unsigned char **test = calloc(3,sizeof(char*));
      *test = "Test";
      test++;
      *test = "This";
      test++;
      *test = "Code";
      int a;
      for(a=0;a<3;a++){
          printf("%s\n",test[a]);
      }
      free(test);
    return 0;
    }

  9. #9
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Well, now that you have changed test, writing test[a] and free(test) is wrong. You should create another char** to save the original value of the pointer.

    Also, instead of an unsigned char**, you probably want a const char**
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  10. #10
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    Quote Originally Posted by Otto45 View Post
    Code:
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <assert.h>
    int main(){
      unsigned char **test = calloc(3,sizeof(char*));
      *test = "Test";
      test++;
      *test = "This";
      test++;
      *test = "Code";
      int a;
      for(a=0;a<3;a++){
          printf("%s\n",test[a]);
      }
      free(test);
    return 0;
    }
    Now that you increment test, you're correctly traversing your array... but you've lost your pointer to the original array. That is, when the for loop begins, test is pointing to the third element of the array, rather than the first.

    There are better ways to do what you want:

    Code:
      unsigned char **test = calloc(3,sizeof(char*));
      *test = "Test";
      *(test+1) = "This";
      *(test+2) = "Code";
    Or the more common exact equivalent:

    Code:
      unsigned char **test = calloc(3,sizeof(char*));
      test[0] = "Test";
      test[1] = "This";
      test[2] = "Code";
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

  11. #11
    Registered User
    Join Date
    Mar 2013
    Posts
    16
    Ah, I get it. I thought that once I started using the array notation in the for loop, it would automatically go to the correct position for test[0], etc.

  12. #12
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    Quote Originally Posted by Otto45 View Post
    Ah, I get it. I thought that once I started using the array notation in the for loop, it would automatically go to the correct position for test[0], etc.
    Not if test no longer holds that value.

    All a pointer really is (under the hood) is a memory address, which is just a number of a certain size appropriate for your operating system & compiler. When you do test++, you change the value of that number, just like you would change the value of any number that you incremented.

    It can't find the "correct" location of test[0] unless test has the same address it initially had, which is the address to the first of your three character pointers.
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Quick question on double precision
    By McFury in forum C++ Programming
    Replies: 13
    Last Post: 02-18-2010, 04:38 AM
  2. Double pointer question
    By newbie30 in forum C Programming
    Replies: 6
    Last Post: 08-20-2009, 10:06 AM
  3. double astrix pointer question..
    By transgalactic2 in forum C Programming
    Replies: 104
    Last Post: 01-19-2009, 05:02 AM
  4. Double Pointer Question
    By krock923 in forum C Programming
    Replies: 12
    Last Post: 12-08-2007, 12:46 AM
  5. Refresh me.. Double pointer's question
    By Ganoosh in forum C++ Programming
    Replies: 6
    Last Post: 07-15-2006, 11:08 AM