Pointer to pointer with lots of examples

Discussion in 'C Programming' started by sheroork, Jul 30, 2006.

  1. sheroork

    sheroork Guest

    Can anyone help me in getting to understand pointer to pointer with
    examples?

    Appritiate in advance.

    Sagar
     
    sheroork, Jul 30, 2006
    #1
    1. Advertising

  2. sheroork said:

    > Can anyone help me in getting to understand pointer to pointer with
    > examples?


    Phone up the Directory Enquiries service (192 if you're in the UK). Tell
    them the name of the person you're looking for, and they'll tell you the
    relevant phone number. You can then use that phone number to contact the
    person you really want to talk to.

    Translation: a pointer tells you where something is. But it, itself, has an
    address, which you might need to find out before you can use it. So a
    pointer to pointer simply tells you where a particular pointer is. A
    pointer is like a phone number. Dereferencing the pointer is like making
    the call. When the guy on the other end gives you another phone number,
    you've just used a pointer (*his* number) to a pointer (the number he gives
    you), and presumably you'll use that new pointer to find the information
    (make the call) you really wanted to find (make).

    Examples are tricky, in that any realistic working example is likely to be
    way too big and complicated to make it a useful example. If you're not
    afraid of big examples, though, let me know and I'll see what I can dig up
    from my code base.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Jul 30, 2006
    #2
    1. Advertising

  3. sheroork wrote:
    > Can anyone help me in getting to understand pointer to pointer with
    > examples?


    int **p;

    p
    +---+
    | ? |
    +---+

    p = malloc(sizeof *p);

    p *p
    +---+ +---+
    | ----->| ? |
    +---+ +---+

    *p = malloc(sizeof **p);

    p *p **p
    +---+ +---+ +---+
    | ----->| ----->| ? |
    +---+ +---+ +---+

    **p = 7;

    p *p **p
    +---+ +---+ +---+
    | ----->| ----->| 7 |
    +---+ +---+ +---+


    August
     
    August Karlstrom, Jul 30, 2006
    #3
  4. sheroork

    Ben Pfaff Guest

    Richard Heathfield <> writes:

    > sheroork said:
    >
    >> Can anyone help me in getting to understand pointer to pointer with
    >> examples?

    >
    > Examples are tricky, in that any realistic working example is likely to be
    > way too big and complicated to make it a useful example. If you're not
    > afraid of big examples, though, let me know and I'll see what I can dig up
    > from my code base.


    Using a pointer to pointer to return a pointer value from a
    function may be a simple way to come up with a short example.
    --
    int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz.\
    \n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
    );while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p\
    );}return 0;}
     
    Ben Pfaff, Jul 30, 2006
    #4
  5. Ben Pfaff said:

    > Richard Heathfield <> writes:
    >
    >> sheroork said:
    >>
    >>> Can anyone help me in getting to understand pointer to pointer with
    >>> examples?

    >>
    >> Examples are tricky, in that any realistic working example is likely to
    >> be way too big and complicated to make it a useful example. If you're not
    >> afraid of big examples, though, let me know and I'll see what I can dig
    >> up from my code base.

    >
    > Using a pointer to pointer to return a pointer value from a
    > function may be a simple way to come up with a short example.


    Be my guest. :)

    The problem with such examples, however, is that they tend to leave the
    reader scratching his head and thinking "okay, I'm seeing some syntax, and
    I think I understand that - but why would anyone do it like /that/ when
    they could just, say, return the pointer value using 'return p;'?" You know
    and I know that such code as foo(&ptr) is actually quite common, and for
    good reason - but it's one thing to know and another to explain.

    Maybe August had the right idea - a dynamic array of dynamic arrays.

    T **p = malloc(rows * sizeof *p);
    if(p != NULL)
    {
    size_t r = 0;
    for(r = 0; r < rows; r++)
    {
    p[r] = malloc(cols * sizeof *p[r]);
    if(p[r] == NULL) { handle_the_error(); }
    }

    Assuming all that worked okay, you now have a dynamically sized array, rows
    * cols elements in size. Whilst there are other ways to achieve this, I
    think pointer to pointer is actually the simplest solution for this
    problem, so it makes a good example. Nice one, August.


    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Jul 30, 2006
    #5
  6. sheroork

    Ben Pfaff Guest

    Richard Heathfield <> writes:

    > Maybe August had the right idea - a dynamic array of dynamic arrays.


    There is in an example of a multidimensional array using a
    pointer-to-pointer in the FAQ. I thought about posting it
    earlier but wasn't sure that it was simple enough.

    6.16: How can I dynamically allocate a multidimensional array?

    A: The traditional solution is to allocate an array of pointers,
    and then initialize each pointer to a dynamically-allocated
    "row." Here is a two-dimensional example:

    #include <stdlib.h>

    int **array1 = malloc(nrows * sizeof(int *));
    for(i = 0; i < nrows; i++)
    array1 = malloc(ncolumns * sizeof(int));

    (In real code, of course, all of malloc's return values would
    be checked.)

    You can keep the array's contents contiguous, at the cost of
    making later reallocation of individual rows more difficult,
    with a bit of explicit pointer arithmetic:

    int **array2 = malloc(nrows * sizeof(int *));
    array2[0] = malloc(nrows * ncolumns * sizeof(int));
    for(i = 1; i < nrows; i++)
    array2 = array2[0] + i * ncolumns;

    In either case, the elements of the dynamic array can be
    accessed with normal-looking array subscripts: arrayx[j]
    (for 0 <= i < nrows and 0 <= j < ncolumns).

    If the double indirection implied by the above schemes is for
    some reason unacceptable, you can simulate a two-dimensional
    array with a single, dynamically-allocated one-dimensional
    array:

    int *array3 = malloc(nrows * ncolumns * sizeof(int));

    However, you must now perform subscript calculations manually,
    accessing the i,jth element with array3[i * ncolumns + j]. (A
    macro could hide the explicit calculation, but invoking it would
    require parentheses and commas which wouldn't look exactly like
    multidimensional array syntax, and the macro would need access
    to at least one of the dimensions, as well. See also question
    6.19.)

    Yet another option is to use pointers to arrays:

    int (*array4)[NCOLUMNS] = malloc(nrows * sizeof(*array4));

    but the syntax starts getting horrific and at most one dimension
    may be specified at run time.

    With all of these techniques, you may of course need to remember
    to free the arrays (which may take several steps; see question
    7.23) when they are no longer needed, and you cannot necessarily
    intermix dynamically-allocated arrays with conventional,
    statically-allocated ones (see question 6.20, and also question
    6.18).

    Finally, in C9X you can use a variable-length array.

    All of these techniques can also be extended to three or more
    dimensions.

    References: C9X Sec. 6.5.5.2.

    --
    "Debugging is twice as hard as writing the code in the first place.
    Therefore, if you write the code as cleverly as possible, you are,
    by definition, not smart enough to debug it."
    --Brian Kernighan
     
    Ben Pfaff, Jul 30, 2006
    #6
  7. sheroork

    Scorpio Guest

    August Karlstrom wrote:
    > sheroork wrote:
    > > Can anyone help me in getting to understand pointer to pointer with
    > > examples?

    >
    > int **p;
    >
    > p
    > +---+
    > | ? |
    > +---+
    >
    > p = malloc(sizeof *p);
    >
    > p *p
    > +---+ +---+
    > | ----->| ? |
    > +---+ +---+
    >
    > *p = malloc(sizeof **p);


    ITYM: *p=malloc(sizeof int);


    > p *p **p
    > +---+ +---+ +---+
    > | ----->| ----->| ? |
    > +---+ +---+ +---+
    >
    > **p = 7;
    >
    > p *p **p
    > +---+ +---+ +---+
    > | ----->| ----->| 7 |
    > +---+ +---+ +---+
    >
    >
    > August


    Sharath A.V

    -In the journey of life, failure is a lesson and success is an illusion.
     
    Scorpio, Jul 31, 2006
    #7
  8. Scorpio said:
    > August Karlstrom wrote:

    <snip>
    >>
    >> *p = malloc(sizeof **p);

    >
    > ITYM: *p=malloc(sizeof int);


    No, HDNMT. For one thing, August's code is conceptually correct no matter
    what the object type to which p points. And secondly, his code - unlike
    yours - will actually compile.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Jul 31, 2006
    #8
  9. sheroork

    Scorpio Guest

    Richard Heathfield wrote:
    > Scorpio said:
    > > August Karlstrom wrote:

    > <snip>
    > >>
    > >> *p = malloc(sizeof **p);

    > >
    > > ITYM: *p=malloc(sizeof int);

    >
    > No, HDNMT. For one thing, August's code is conceptually correct no matter
    > what the object type to which p points. And secondly, his code - unlike
    > yours - will actually compile.


    Sorry, I was mistaken and yes, August's code is correct.
    But I actually meant: *p=malloc(sizeof(int));
    Is something wrong with this?

    Even the code quoted by Ben from the FAQ is as follows:
    int **array1 = malloc(nrows * sizeof(int *));
    for(i = 0; i < nrows; i++)
    array1 = malloc(ncolumns * sizeof(int));

    BTW, what does HDNMT mean? I did try to find out, but found no results.

    Sharath A.V
     
    Scorpio, Jul 31, 2006
    #9
  10. Scorpio said:

    > Richard Heathfield wrote:
    >> Scorpio said:
    >> > August Karlstrom wrote:

    >> <snip>
    >> >>
    >> >> *p = malloc(sizeof **p);
    >> >
    >> > ITYM: *p=malloc(sizeof int);

    >>
    >> No, HDNMT. For one thing, August's code is conceptually correct no matter
    >> what the object type to which p points. And secondly, his code - unlike
    >> yours - will actually compile.

    >
    > Sorry, I was mistaken and yes, August's code is correct.
    > But I actually meant: *p=malloc(sizeof(int));
    > Is something wrong with this?


    It will at least compile, but it's inferior to August's version, because
    you're nailing the type to the call, possibly causing a maintenance
    headache further down the line.

    > Even the code quoted by Ben from the FAQ is as follows:
    > int **array1 = malloc(nrows * sizeof(int *));
    > for(i = 0; i < nrows; i++)
    > array1 = malloc(ncolumns * sizeof(int));


    Yeah, the FAQ is good but nobody ever claimed it was perfect.

    > BTW, what does HDNMT mean? I did try to find out, but found no results.


    He Did Not Mean That. (i.e. he did not mean what you thought he meant.)

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Jul 31, 2006
    #10
  11. sheroork

    Morris Dovey Guest

    Morris Dovey, Jul 31, 2006
    #11
  12. sheroork

    Flash Gordon Guest

    Morris Dovey wrote:
    > sheroork (in )
    > said:
    >
    > | Can anyone help me in getting to understand pointer to pointer with
    > | examples?
    >
    > Sagar...
    >
    > The explanations posted so far look good. These two links make up
    > another example of how pointers to pointers might be used:
    >
    > http://www.iedu.com/mrd/c/tokenize.c
    > http://www.iedu.com/mrd/c/tokfile.c


    They look more like an example of how not to write C to me.

    Rather than having a tokenize.h containing the prototype for the
    tokenize function it has the prototype repeated in tokfile.c. So you
    have to maintain it in two places with no help from the compiler.

    Using a file scope variable for the function to determine if a character
    is a word separator or part of a word instead of passing it down. What
    is worse, a single character name for it!

    Assuming ASCII or similar character encoding instead of using the
    portable standard is* functions.

    Increasing the hard to follow coupling by using another file scope
    variable s to hold a pointer to the character being processed. The
    author seems to have a major objection to using parameters!

    Using recursion for what could more simply be implemented with a for
    loop, and the state being passed down via the afore mentioned file scope
    variables instead of parameters!

    That code is so needlessly convoluted that pointing a beginner at it is
    tantamount to cruelty!
    --
    Flash Gordon
    Still sigless on this computer.
     
    Flash Gordon, Jul 31, 2006
    #12
  13. sheroork

    sheroork Guest

    Thanks friends for all your time and knowledge you have posted.
    I will be greatful for your postings.

    Thanks,
    Sagar
     
    sheroork, Jul 31, 2006
    #13
  14. sheroork

    Tom St Denis Guest

    August Karlstrom wrote:
    > sheroork wrote:
    > > Can anyone help me in getting to understand pointer to pointer with
    > > examples?

    >
    > int **p;
    >
    > p
    > +---+
    > | ? |
    > +---+
    >
    > p = malloc(sizeof *p);
    >
    > p *p
    > +---+ +---+
    > | ----->| ? |
    > +---+ +---+
    >
    > *p = malloc(sizeof **p);
    >
    > p *p **p
    > +---+ +---+ +---+
    > | ----->| ----->| ? |
    > +---+ +---+ +---+
    >
    > **p = 7;
    >
    > p *p **p
    > +---+ +---+ +---+
    > | ----->| ----->| 7 |
    > +---+ +---+ +---+


    I, for one, welcome our ASCII art overlords.

    Tom
     
    Tom St Denis, Jul 31, 2006
    #14
  15. sheroork

    Default User Guest

    Richard Heathfield wrote:

    > Scorpio said:


    > > Sorry, I was mistaken and yes, August's code is correct.
    > > But I actually meant: *p=malloc(sizeof(int));
    > > Is something wrong with this?

    >
    > It will at least compile, but it's inferior to August's version,
    > because you're nailing the type to the call, possibly causing a
    > maintenance headache further down the line.



    After all, we just got done diagnosing an incorrect malloc call in
    another thread. The deference the target method isn't fool-proof, of
    course, but it's closer. You still have the cut and paste problem, but
    it's a tad more recognizable because you have the two variable names on
    the same line, whereas the types are often widely separated.



    Brian
     
    Default User, Jul 31, 2006
    #15
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Cor van Loos
    Replies:
    2
    Views:
    503
  2. Mike Hnatt
    Replies:
    4
    Views:
    436
    Steve C. Orr [MVP, MCSD]
    Nov 3, 2003
  3. Timmy T
    Replies:
    0
    Views:
    298
    Timmy T
    Mar 6, 2004
  4. brad
    Replies:
    9
    Views:
    383
    Bruno Desthuilliers
    Jun 19, 2008
  5. coolneo
    Replies:
    9
    Views:
    202
    coolneo
    Jan 30, 2007
Loading...

Share This Page