Thread: Can someone further explain an explantation? Triple pointers vs double pointers

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

    Can someone further explain an explantation? Triple pointers vs double pointers

    Code:
    void init(char***subjects_array,char***courses_array)
     {
    
    
         int i;
    
        *subjects_array =(char**) malloc (100*sizeof(char*));
        *courses_array =(char**) malloc(100*sizeof(char*));
    
    
        for(i =0; i < INITIAL_COURSE_SIZE; i++)
       {
         (*subjects)[i]=(char*) malloc(4*sizeof(char));
         (*courses)[i]=(char*) malloc(6*sizeof(char));
       } 
    
    
      }// end of Triple pointer version
    
    
                           //  Double Pointer Version
              void init(char** subject_array,char** courses_array){                   
    
      subject_array =(char**) malloc (100*sizeof(char*));
      courses_array =(char**) malloc (100*sizeof(char*));
    
     for(int i =0; i<100; i++){
        subject_array[i]=(char*) malloc(4*sizeof(char));
        courses_array[i]=(char*) malloc (6*sizeof(char));
       }
       }


    My question is: Both versions initiate a 2d array. So what purpose does the triple pointer version serve? It seems that the extra level of indirection serves no "purpose".

    In the triple pointer version, it would allow me to allocate double pointers...But in either version no double pointers were allocated. Could you point out where double pointers are assigned especially in the triple pointer version


    Here was the explantation:
    Code:
    
    
    Code:
    Since C passes parameters, including pointers, only by value, you need to add an extra level of indirection (i.e. an asterisk) for any parameter that you wish to modify inside a function.
    This provides the clue to what's going on: normally, you need two asterisks for a 2D array, i.e. char **twoD. However, since init allocates a new array, you need an extra level of indirection, i.e.
    void init(char***subjects_array,char***courses_array)



    Last edited by tmac619619; 08-29-2015 at 12:41 PM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by tmac619619
    My question is: Both versions initiate a 2d array. So what purpose does the triple pointer version serve? It seems that the extra level of indirection serves no "purpose".
    It serves a very important purpose: so that the "double pointer" from the caller will be modified from within the function. Consider a simpler example:
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    void foo(int *p)
    {
        p = malloc(sizeof(*p));
        printf("foo: %p\n", (void*)p);
    }
    
    void bar(int **p)
    {
        *p = malloc(sizeof(**p));
        printf("bar: %p\n", (void*)*p);
    }
    
    int main(void)
    {
        int *p1 = NULL;
        int *p2 = NULL;
        foo(p1);
        bar(&p2);
        printf("p1=%p; p2=%p\n", (void*)p1, (void*)p2);
        free(p1);
        free(p2);
        return 0;
    }
    When I compile and run the above program, I get the output:
    Code:
    foo: 0x11dc010
    bar: 0x11dc030
    p1=(nil); p2=0x11dc030
    This is hugely important as it means that from the perspective of the main function, foo did nothing, but we know that malloc did succeed in foo. In bar, on the other hand, malloc not only succeeded, but the main function's p2 was changed as was desired.

    That said, I suggest that you avoid "triple pointers". Instead of being a Three Star Programmer, make use of some abstraction, e.g., define a struct type for a subject and another struct type for a course, upon which you could write:
    Code:
    void init(struct subject **subjects_array, struct course **courses_array)
    You might even go further to define a struct for a list of subjects and another struct for a list for courses, reducing the indirection to just:
    Code:
    void init(struct subject_list *subjects, struct course_list *courses)
    Last edited by laserlight; 08-29-2015 at 12:55 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
    Oct 2012
    Posts
    158
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    void foo(int *p)
    {
        p = malloc(sizeof(*p));
        printf("foo: %p\n", (void*)p);
    }
    
    void bar(int **p)
    {
        *p = malloc(sizeof(**p));
        printf("bar: %p\n", (void*)p);
    }
    
    int main(void)
    {
        int *p1 = NULL;
        int *p2 = NULL;
        foo(p1);
        bar(&p2);
        printf("p1=%p; p2=%p\n", (void*)p1, (void*)p2);
        free(p1);
        free(p2);
        return 0;
    }
    

    "This is hugely important as it means that from the perspective of the main function, foo did nothing, but we know that malloc did succeed in foo.

    Thank you! Could you explain a little more as to why foo did nothing?

    As far as i know, a pointer was passed to foo. malloc occurred and a pointer points to memory. So why doesn't main know what happened?

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by tmac619619
    Could you explain a little more as to why foo did nothing?

    As far as i know, a pointer was passed to foo. malloc occurred and a pointer points to memory. So why doesn't main know what happened?
    Well, let's consider an even simpler example:
    Code:
    #include <stdio.h>
    
    void foo(int n)
    {
        n = 123;
    }
    
    void bar(int *p)
    {
        *p = 123;
    }
    
    int main(void)
    {
        int n1 = 0;
        int n2 = 0;
        foo(n1);
        bar(&n2);
        printf("n1=%d; n2=%d\n", n1, n2);
        return 0;
    }
    Compiling and running the above program, I get the output:
    Code:
    n1=0; n2=123
    As far as I know, 123 was assigned to n in foo. So why does n1 in main still have the value of 0? It is as if foo did nothing, but clearly it assigned 123 to n!
    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
    Oct 2012
    Posts
    158
    Thanks I understand!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Can someone explain this to me (beginner w/ pointers)?
    By klawson88 in forum C Programming
    Replies: 7
    Last Post: 10-02-2010, 10:07 PM
  2. triple pointers *** question
    By someprogr in forum C Programming
    Replies: 8
    Last Post: 01-07-2009, 05:10 AM
  3. Pointers, useful? Please explain!
    By wildex999 in forum C++ Programming
    Replies: 16
    Last Post: 02-23-2006, 11:48 AM
  4. Somebody please explain pointers
    By 7smurfs in forum C++ Programming
    Replies: 7
    Last Post: 12-09-2004, 08:08 PM
  5. Replies: 18
    Last Post: 06-14-2003, 10:40 AM