Pointer-to-pointer-to-pointer question

Discussion in 'C Programming' started by masood.iqbal@lycos.com, Feb 3, 2005.

  1. Guest

    The code example below shows the dynamic allocation of a 2D array. I
    must admit that it took quite a while for me to get there (I already
    have another posting to that effect), but I am glad that I finally got
    it working. Now here's the problem:

    I am able to get the 2D array dynamically allocated correctly as long
    as I am doing it "in-line" (i.e. without invoking any function). The
    moment I try to do it in another function, I get a core dump. Any help
    will be appreciated.

    Since this function is expected to update a pointer-to-pointer type, I
    am actually passing the pointer-to-pointer-to-pointer type to the
    function. What am I missing here?

    You can see that the source code works correctly when I am perform 2D
    array initialization "in-line" (i.e. by not invoking a function
    call) simply by un-commenting the line

    /* #define INLINE_INIT */

    Masood

    /******************************************************/
    #include <stdio.h>
    #include <stdlib.h>

    /*#define INLINE_INIT*/

    #define MAXROWS 3
    #define MAXCOLS 5


    void
    buildTbl(int ***tblPtr, size_t numRows, size_t numCols)
    {
    *tblPtr = (int **)malloc(numRows*sizeof(int*));
    /* C++ : *tblPtr = new (int*)[numRows]; */

    for(size_t i = 0; i < numCols; i++)
    *tblPtr = (int *)malloc(numCols*sizeof(int));
    /* C++: *tblPtr = new (int)[numCols]; */
    }


    main()
    {
    int startVal = 5;

    int **tbl;

    #ifdef INLINE_INIT
    tbl = (int **)malloc(MAXROWS*sizeof(int*));
    /* C++ : tbl = new (int*)[MAXROWS]; */

    for(size_t i = 0; i < MAXCOLS; i++)
    tbl = (int *)malloc(MAXCOLS*sizeof(int));
    /* C++: tbl = new (int)[MAXCOLS]; */
    #else
    buildTbl(&tbl, MAXROWS, MAXCOLS);
    #endif

    for(size_t row = 0; row < MAXROWS; row++)
    for(size_t col = 0; col < MAXCOLS; col++)
    tbl[row][col] = startVal++;

    for(size_t row = 0; row < MAXROWS; row++)
    for(size_t col = 0; col < MAXCOLS; col++)
    printf("Row: %d, Col: %d => %d\n",
    row, col, tbl[row][col]);
    return 0;
    }
    , Feb 3, 2005
    #1
    1. Advertising

  2. Tobias Oed Guest

    wrote:

    > Masood
    >
    > /******************************************************/
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > /*#define INLINE_INIT*/
    >
    > #define MAXROWS 3
    > #define MAXCOLS 5
    >
    >
    > void
    > buildTbl(int ***tblPtr, size_t numRows, size_t numCols)
    > {
    > *tblPtr = (int **)malloc(numRows*sizeof(int*));
    > /* C++ : *tblPtr = new (int*)[numRows]; */
    >
    > for(size_t i = 0; i < numCols; i++)
    > *tblPtr = (int *)malloc(numCols*sizeof(int));


    (*tblPtr) = ...

    Note that x = malloc(n * sizeof *x);
    is preferred to x = (type *) malloc(n * sizeof(type);
    You should check that malloc doesn't return NULL.
    You could change the return type of buildTbl to int ** and
    return the array that way instead of through the parameter.

    Do I remember that stuff Ok? Nice to see most of you are
    still here!

    Tobias

    > /* C++: *tblPtr = new (int)[numCols]; */
    > }
    >
    >
    > main()
    > {
    > int startVal = 5;
    >
    > int **tbl;
    >
    > #ifdef INLINE_INIT
    > tbl = (int **)malloc(MAXROWS*sizeof(int*));
    > /* C++ : tbl = new (int*)[MAXROWS]; */
    >
    > for(size_t i = 0; i < MAXCOLS; i++)
    > tbl = (int *)malloc(MAXCOLS*sizeof(int));
    > /* C++: tbl = new (int)[MAXCOLS]; */
    > #else
    > buildTbl(&tbl, MAXROWS, MAXCOLS);
    > #endif
    >
    > for(size_t row = 0; row < MAXROWS; row++)
    > for(size_t col = 0; col < MAXCOLS; col++)
    > tbl[row][col] = startVal++;
    >
    > for(size_t row = 0; row < MAXROWS; row++)
    > for(size_t col = 0; col < MAXCOLS; col++)
    > printf("Row: %d, Col: %d => %d\n",
    > row, col, tbl[row][col]);
    > return 0;
    > }
    Tobias Oed, Feb 3, 2005
    #2
    1. Advertising

  3. Michael Mair Guest

    wrote:
    > The code example below shows the dynamic allocation of a 2D array. I
    > must admit that it took quite a while for me to get there (I already
    > have another posting to that effect), but I am glad that I finally got
    > it working. Now here's the problem:
    >
    > I am able to get the 2D array dynamically allocated correctly as long
    > as I am doing it "in-line" (i.e. without invoking any function). The
    > moment I try to do it in another function, I get a core dump. Any help
    > will be appreciated.
    >
    > Since this function is expected to update a pointer-to-pointer type, I
    > am actually passing the pointer-to-pointer-to-pointer type to the
    > function. What am I missing here?


    You can get lost with the intricacies of C.
    One "trick" to get around it: Use a local "pointer-to-pointer type"
    variable to do as you always did and assign its value to the object
    your "pointer-to-pointer-to-pointer type" argument points to.
    -> Essentially the same code, one additional line.
    (You perform all operations on *tblPtr which essentially means that
    you could also work with a int **tbl and put *tblPtr=tbl at the end
    if everything worked out)
    If you follow Tobias's advice, it becomes even easier.

    > You can see that the source code works correctly when I am perform 2D
    > array initialization "in-line" (i.e. by not invoking a function
    > call) simply by un-commenting the line
    >
    > /* #define INLINE_INIT */
    >
    > Masood

    [snip: Code]

    Tobias Oed has already mentioned everything I can see.
    Follow _every_ point of his advice regarding malloc().

    BTW: Thank you for providing a good minimal example!


    Cheers
    Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
    Michael Mair, Feb 3, 2005
    #3
  4. wrote:

    > void
    > buildTbl(int ***tblPtr, size_t numRows, size_t numCols)
    > {
    > *tblPtr = (int **)malloc(numRows*sizeof(int*));
    > /* C++ : *tblPtr = new (int*)[numRows]; */
    >
    > for(size_t i = 0; i < numCols; i++)


    The condition should be i < numRows.

    > *tblPtr = (int *)malloc(numCols*sizeof(int));


    This will access memory not belonging to tblPtr if i is greater than 0.
    Change it to the following:
    (*tblPtr) = malloc(numCols*sizeof(int));
    It's also a good idea to check the return value of malloc().


    Christian
    Christian Kandeler, Feb 3, 2005
    #4
  5. Amit Guest

    wrote:
    >
    > /* #define INLINE_INIT */
    >
    > Masood


    > void
    > buildTbl(int ***tblPtr, size_t numRows, size_t numCols)
    > {
    > *tblPtr = (int **)malloc(numRows*sizeof(int*));
    > /* C++ : *tblPtr = new (int*)[numRows]; */
    >
    > for(size_t i = 0; i < numCols; i++)
    > *tblPtr = (int *)malloc(numCols*sizeof(int));

    (*tblPtr) = (int *)malloc(numCols*sizeof(int)); <------
    > /* C++: *tblPtr = new (int)[numCols]; */
    > }
    >


    I am not a master of C, but what i can see is the problem of precedence.
    And yes you should check the return value of malloc also.
    Amit, Feb 3, 2005
    #5
  6. wrote:
    > The code example below shows the dynamic allocation of a 2D array. I
    > must admit that it took quite a while for me to get there (I already
    > have another posting to that effect), but I am glad that I finally got
    > it working. Now here's the problem:
    >
    > I am able to get the 2D array dynamically allocated correctly as long
    > as I am doing it "in-line" (i.e. without invoking any function). The
    > moment I try to do it in another function, I get a core dump. Any help
    > will be appreciated.
    >
    > Since this function is expected to update a pointer-to-pointer type, I
    > am actually passing the pointer-to-pointer-to-pointer type to the
    > function. What am I missing here?
    >
    > You can see that the source code works correctly when I am perform 2D
    > array initialization "in-line" (i.e. by not invoking a function
    > call) simply by un-commenting the line
    >
    > /* #define INLINE_INIT */
    >
    > Masood
    >
    > /******************************************************/
    > #include <stdio.h>
    > #include <stdlib.h>
    >
    > /*#define INLINE_INIT*/
    >
    > #define MAXROWS 3
    > #define MAXCOLS 5
    >
    >
    > void
    > buildTbl(int ***tblPtr, size_t numRows, size_t numCols)
    > {


    Return an int** instead.

    > *tblPtr = (int **)malloc(numRows*sizeof(int*));
    > /* C++ : *tblPtr = new (int*)[numRows]; */
    >
    > for(size_t i = 0; i < numCols; i++)
    > *tblPtr = (int *)malloc(numCols*sizeof(int));
    > /* C++: *tblPtr = new (int)[numCols]; */
    > }


    Instead of allocating memory so many times, a better method
    would be to call malloc only once to allocate all the
    memory you need. This would improve the efficiency of
    your code. (See example below.)

    >
    >
    > main()
    > {


    int main (void)... is better.

    > int startVal = 5;
    >
    > int **tbl;
    >
    > #ifdef INLINE_INIT
    > tbl = (int **)malloc(MAXROWS*sizeof(int*));


    Don't cast malloc or any other function that
    returns a pointer unless you really know what you are
    doing.

    Should be tbl = malloc(...);

    > /* C++ : tbl = new (int*)[MAXROWS]; */
    >
    > for(size_t i = 0; i < MAXCOLS; i++)


    for (size_t i ... ) won't work with C'89.
    Avoid it.

    > tbl = (int *)malloc(MAXCOLS*sizeof(int));


    See above.

    > /* C++: tbl = new (int)[MAXCOLS]; */
    > #else
    > buildTbl(&tbl, MAXROWS, MAXCOLS);
    > #endif
    >
    > for(size_t row = 0; row < MAXROWS; row++)
    > for(size_t col = 0; col < MAXCOLS; col++)
    > tbl[row][col] = startVal++;
    >
    > for(size_t row = 0; row < MAXROWS; row++)
    > for(size_t col = 0; col < MAXCOLS; col++)
    > printf("Row: %d, Col: %d => %d\n",
    > row, col, tbl[row][col]);
    > return 0;
    > }
    >


    I've seen code that did not have proper braces
    to block the scope of such for loops. The problem
    I faced was that the formatting of the code was
    lost and the code that followed that for
    statement was a large "if statement".
    Let me tell you, it wasn't easy to reformat that
    code manually. Properly placing braces can save you a lot of time.
    Use them.

    Additionally, I don't see why, after you've been told before,
    you don't use a proper NG client to post. It is *difficult*
    to read unindented code. Please use a good client.


    /* grid_alloc.c. */
    #include <stdlib.h>

    int **grid_alloc (size_int rows, size_int cols)
    {
    int **mem; /* allocated memory */
    int *p; /* temporary ptr */
    size_int r; /* row index */

    mem = malloc (rows * cols * sizeof(int) + rows * sizeof(*mem));
    if(mem != NULL)
    {
    /* memory layout:
    * [ pointers: one pointer to each row of data ][ data ]
    */
    for (r = 0, p = (int*)mem + rows; r < rows; ++r, p += cols)
    {
    mem[r] = p;
    }
    }

    return mem;
    }

    /* ... */

    This allows you to use array syntax to address elements.
    Don't forget to use free() when you're done with it, however.

    Regards,
    Jonathan.

    --
    Email: "jonathan [period] burd [commercial-at] gmail [period] com" sans-WSP

    "We must do something. This is something. Therefore, we must do this."
    - Keith Thompson
    Jonathan Burd, Feb 3, 2005
    #6
  7. Jonathan Burd wrote:
    > wrote:
    >
    >> The code example below shows the dynamic allocation of a 2D array. I
    >> must admit that it took quite a while for me to get there (I already
    >> have another posting to that effect), but I am glad that I finally got
    >> it working. Now here's the problem:
    >>
    >> I am able to get the 2D array dynamically allocated correctly as long
    >> as I am doing it "in-line" (i.e. without invoking any function). The
    >> moment I try to do it in another function, I get a core dump. Any help
    >> will be appreciated.
    >>
    >> Since this function is expected to update a pointer-to-pointer type, I
    >> am actually passing the pointer-to-pointer-to-pointer type to the
    >> function. What am I missing here?
    >>
    >> You can see that the source code works correctly when I am perform 2D
    >> array initialization "in-line" (i.e. by not invoking a function
    >> call) simply by un-commenting the line
    >>
    >> /* #define INLINE_INIT */
    >>
    >> Masood
    >>
    >> /******************************************************/
    >> #include <stdio.h>
    >> #include <stdlib.h>
    >>
    >> /*#define INLINE_INIT*/
    >>
    >> #define MAXROWS 3
    >> #define MAXCOLS 5
    >>
    >>
    >> void
    >> buildTbl(int ***tblPtr, size_t numRows, size_t numCols)
    >> {

    >
    >
    > Return an int** instead.
    >
    >> *tblPtr = (int **)malloc(numRows*sizeof(int*));
    >> /* C++ : *tblPtr = new (int*)[numRows]; */
    >>
    >> for(size_t i = 0; i < numCols; i++)
    >> *tblPtr = (int *)malloc(numCols*sizeof(int));
    >> /* C++: *tblPtr = new (int)[numCols]; */
    >> }

    >
    >
    > Instead of allocating memory so many times, a better method
    > would be to call malloc only once to allocate all the
    > memory you need. This would improve the efficiency of
    > your code. (See example below.)
    >
    >>
    >>
    >> main()
    >> {

    >
    >
    > int main (void)... is better.
    >
    >> int startVal = 5;
    >>
    >> int **tbl;
    >>
    >> #ifdef INLINE_INIT
    >> tbl = (int **)malloc(MAXROWS*sizeof(int*));

    >
    >
    > Don't cast malloc or any other function that
    > returns a pointer unless you really know what you are
    > doing.
    >
    > Should be tbl = malloc(...);
    >
    >> /* C++ : tbl = new (int*)[MAXROWS]; */
    >>
    >> for(size_t i = 0; i < MAXCOLS; i++)

    >
    >
    > for (size_t i ... ) won't work with C'89.
    > Avoid it.
    >
    >> tbl = (int *)malloc(MAXCOLS*sizeof(int));

    >
    >
    > See above.
    >
    >> /* C++: tbl = new (int)[MAXCOLS]; */
    >> #else
    >> buildTbl(&tbl, MAXROWS, MAXCOLS);
    >> #endif
    >>
    >> for(size_t row = 0; row < MAXROWS; row++)
    >> for(size_t col = 0; col < MAXCOLS; col++)
    >> tbl[row][col] = startVal++;
    >>
    >> for(size_t row = 0; row < MAXROWS; row++)
    >> for(size_t col = 0; col < MAXCOLS; col++)
    >> printf("Row: %d, Col: %d => %d\n",
    >> row, col, tbl[row][col]);
    >> return 0;
    >> }
    >>

    >
    > I've seen code that did not have proper braces
    > to block the scope of such for loops. The problem
    > I faced was that the formatting of the code was
    > lost and the code that followed that for
    > statement was a large "if statement".
    > Let me tell you, it wasn't easy to reformat that
    > code manually. Properly placing braces can save you a lot of time.
    > Use them.
    >
    > Additionally, I don't see why, after you've been told before,
    > you don't use a proper NG client to post. It is *difficult*
    > to read unindented code. Please use a good client.
    >
    >
    > /* grid_alloc.c. */
    > #include <stdlib.h>
    >
    > int **grid_alloc (size_int rows, size_int cols)
    > {
    > int **mem; /* allocated memory */
    > int *p; /* temporary ptr */
    > size_int r; /* row index */


    Typos. Should be size_int should be size_t. The editor
    I was using to search-n-replace goofed. :|

    > mem = malloc (rows * cols * sizeof(int) + rows * sizeof(*mem));
    > if(mem != NULL)
    > {
    > /* memory layout:
    > * [ pointers: one pointer to each row of data ][ data ]
    > */
    > for (r = 0, p = (int*)mem + rows; r < rows; ++r, p += cols)
    > {
    > mem[r] = p;
    > }
    > }
    >
    > return mem;
    > }
    >
    > /* ... */
    >
    > This allows you to use array syntax to address elements.
    > Don't forget to use free() when you're done with it, however.
    >
    > Regards,
    > Jonathan.
    >



    --
    Email: "jonathan [period] burd [commercial-at] gmail [period] com" sans-WSP

    "We must do something. This is something. Therefore, we must do this."
    - Keith Thompson
    Jonathan Burd, Feb 3, 2005
    #7
  8. On 2 Feb 2005 20:26:42 -0800, wrote:

    >The code example below shows the dynamic allocation of a 2D array. I
    >must admit that it took quite a while for me to get there (I already
    >have another posting to that effect), but I am glad that I finally got
    >it working. Now here's the problem:
    >
    >I am able to get the 2D array dynamically allocated correctly as long
    >as I am doing it "in-line" (i.e. without invoking any function). The
    >moment I try to do it in another function, I get a core dump. Any help
    >will be appreciated.
    >
    >Since this function is expected to update a pointer-to-pointer type, I
    >am actually passing the pointer-to-pointer-to-pointer type to the
    >function. What am I missing here?
    >
    >You can see that the source code works correctly when I am perform 2D
    >array initialization "in-line" (i.e. by not invoking a function
    >call) simply by un-commenting the line
    >
    >/* #define INLINE_INIT */
    >
    >Masood
    >
    >/******************************************************/
    >#include <stdio.h>
    >#include <stdlib.h>
    >
    >/*#define INLINE_INIT*/
    >
    >#define MAXROWS 3
    >#define MAXCOLS 5
    >
    >
    >void
    >buildTbl(int ***tblPtr, size_t numRows, size_t numCols)
    >{
    >*tblPtr = (int **)malloc(numRows*sizeof(int*));
    >/* C++ : *tblPtr = new (int*)[numRows]; */
    >
    >for(size_t i = 0; i < numCols; i++)
    >*tblPtr = (int *)malloc(numCols*sizeof(int));


    This line is interpreted as
    *(tblPtr) = ...

    You want
    (*tblPtr) = ...

    The parentheses are not optional.

    >/* C++: *tblPtr = new (int)[numCols]; */
    >}
    >
    >
    >main()
    >{
    >int startVal = 5;
    >
    >int **tbl;
    >
    >#ifdef INLINE_INIT
    >tbl = (int **)malloc(MAXROWS*sizeof(int*));
    >/* C++ : tbl = new (int*)[MAXROWS]; */
    >
    >for(size_t i = 0; i < MAXCOLS; i++)
    >tbl = (int *)malloc(MAXCOLS*sizeof(int));
    >/* C++: tbl = new (int)[MAXCOLS]; */
    >#else
    >buildTbl(&tbl, MAXROWS, MAXCOLS);
    >#endif
    >
    >for(size_t row = 0; row < MAXROWS; row++)
    >for(size_t col = 0; col < MAXCOLS; col++)
    >tbl[row][col] = startVal++;
    >
    >for(size_t row = 0; row < MAXROWS; row++)
    >for(size_t col = 0; col < MAXCOLS; col++)
    >printf("Row: %d, Col: %d => %d\n",
    >row, col, tbl[row][col]);
    > return 0;
    >}




    <<Remove the del for email>>
    Barry Schwarz, Feb 4, 2005
    #8
  9. On 2 Feb 2005 20:26:42 -0800, wrote:

    >The code example below shows the dynamic allocation of a 2D array. I
    >must admit that it took quite a while for me to get there (I already
    >have another posting to that effect), but I am glad that I finally got
    >it working. Now here's the problem:
    >
    >I am able to get the 2D array dynamically allocated correctly as long
    >as I am doing it "in-line" (i.e. without invoking any function). The
    >moment I try to do it in another function, I get a core dump. Any help
    >will be appreciated.
    >
    >Since this function is expected to update a pointer-to-pointer type, I
    >am actually passing the pointer-to-pointer-to-pointer type to the
    >function. What am I missing here?
    >
    >You can see that the source code works correctly when I am perform 2D
    >array initialization "in-line" (i.e. by not invoking a function
    >call) simply by un-commenting the line
    >
    >/* #define INLINE_INIT */
    >
    >Masood
    >
    >/******************************************************/
    >#include <stdio.h>
    >#include <stdlib.h>
    >
    >/*#define INLINE_INIT*/
    >
    >#define MAXROWS 3
    >#define MAXCOLS 5
    >
    >
    >void
    >buildTbl(int ***tblPtr, size_t numRows, size_t numCols)
    >{
    >*tblPtr = (int **)malloc(numRows*sizeof(int*));
    >/* C++ : *tblPtr = new (int*)[numRows]; */
    >
    >for(size_t i = 0; i < numCols; i++)
    >*tblPtr = (int *)malloc(numCols*sizeof(int));


    This line is interpreted as
    *(tblPtr) = ...

    You want
    (*tblPtr) = ...

    The parentheses are not optional.

    >/* C++: *tblPtr = new (int)[numCols]; */
    >}
    >
    >
    >main()
    >{
    >int startVal = 5;
    >
    >int **tbl;
    >
    >#ifdef INLINE_INIT
    >tbl = (int **)malloc(MAXROWS*sizeof(int*));
    >/* C++ : tbl = new (int*)[MAXROWS]; */
    >
    >for(size_t i = 0; i < MAXCOLS; i++)
    >tbl = (int *)malloc(MAXCOLS*sizeof(int));
    >/* C++: tbl = new (int)[MAXCOLS]; */
    >#else
    >buildTbl(&tbl, MAXROWS, MAXCOLS);
    >#endif
    >
    >for(size_t row = 0; row < MAXROWS; row++)
    >for(size_t col = 0; col < MAXCOLS; col++)
    >tbl[row][col] = startVal++;
    >
    >for(size_t row = 0; row < MAXROWS; row++)
    >for(size_t col = 0; col < MAXCOLS; col++)
    >printf("Row: %d, Col: %d => %d\n",
    >row, col, tbl[row][col]);
    > return 0;
    >}




    <<Remove the del for email>>
    Barry Schwarz, Feb 4, 2005
    #9
  10. On 2 Feb 2005 20:26:42 -0800, wrote:

    >The code example below shows the dynamic allocation of a 2D array. I
    >must admit that it took quite a while for me to get there (I already
    >have another posting to that effect), but I am glad that I finally got
    >it working. Now here's the problem:
    >
    >I am able to get the 2D array dynamically allocated correctly as long
    >as I am doing it "in-line" (i.e. without invoking any function). The
    >moment I try to do it in another function, I get a core dump. Any help
    >will be appreciated.
    >
    >Since this function is expected to update a pointer-to-pointer type, I
    >am actually passing the pointer-to-pointer-to-pointer type to the
    >function. What am I missing here?
    >
    >You can see that the source code works correctly when I am perform 2D
    >array initialization "in-line" (i.e. by not invoking a function
    >call) simply by un-commenting the line
    >
    >/* #define INLINE_INIT */
    >
    >Masood
    >
    >/******************************************************/
    >#include <stdio.h>
    >#include <stdlib.h>
    >
    >/*#define INLINE_INIT*/
    >
    >#define MAXROWS 3
    >#define MAXCOLS 5
    >
    >
    >void
    >buildTbl(int ***tblPtr, size_t numRows, size_t numCols)
    >{
    >*tblPtr = (int **)malloc(numRows*sizeof(int*));
    >/* C++ : *tblPtr = new (int*)[numRows]; */
    >
    >for(size_t i = 0; i < numCols; i++)
    >*tblPtr = (int *)malloc(numCols*sizeof(int));


    This line is interpreted as
    *(tblPtr) = ...

    You want
    (*tblPtr) = ...

    The parentheses are not optional.

    >/* C++: *tblPtr = new (int)[numCols]; */
    >}
    >
    >
    >main()
    >{
    >int startVal = 5;
    >
    >int **tbl;
    >
    >#ifdef INLINE_INIT
    >tbl = (int **)malloc(MAXROWS*sizeof(int*));
    >/* C++ : tbl = new (int*)[MAXROWS]; */
    >
    >for(size_t i = 0; i < MAXCOLS; i++)
    >tbl = (int *)malloc(MAXCOLS*sizeof(int));
    >/* C++: tbl = new (int)[MAXCOLS]; */
    >#else
    >buildTbl(&tbl, MAXROWS, MAXCOLS);
    >#endif
    >
    >for(size_t row = 0; row < MAXROWS; row++)
    >for(size_t col = 0; col < MAXCOLS; col++)
    >tbl[row][col] = startVal++;
    >
    >for(size_t row = 0; row < MAXROWS; row++)
    >for(size_t col = 0; col < MAXCOLS; col++)
    >printf("Row: %d, Col: %d => %d\n",
    >row, col, tbl[row][col]);
    > return 0;
    >}




    <<Remove the del for email>>
    Barry Schwarz, Feb 4, 2005
    #10
  11. Chris Torek Guest

    [Side note: the article to which I am posting a follow-up got posted
    three times, with three different message-IDs. Software glitch, I
    presume.]

    >On 2 Feb 2005 20:26:42 -0800, wrote:
    >>for(size_t i = 0; i < numCols; i++)
    >>*tblPtr = (int *)malloc(numCols*sizeof(int));


    In article <>
    Barry Schwarz <> wrote:
    >This line is interpreted as
    > *(tblPtr) = ...
    >
    >You want
    > (*tblPtr) = ...
    >
    >The parentheses are not optional.


    Right. Note, however, that if for some reason one finds the
    parenthesized form objectionable, (*p) can be rewritten as
    p[0]. (Likewise, p->field can be rewritten as p[0].field.)

    I think this particular rewrite is misleading and would avoid
    it myself. In fact, I would probably use code of the form:

    nonvoid_return_type some_fn(T ***ptable, ...) {
    T **table;

    ... do all the local work with table and table ...

    *ptable = table;
    return other_useful_return_value;
    }

    or, as in this particular case (where the function had "void" as
    its return type), just return a "T **" value and eliminate the
    three-levels-deep pointer argument.
    --
    In-Real-Life: Chris Torek, Wind River Systems
    Salt Lake City, UT, USA (40°39.22'N, 111°50.29'W) +1 801 277 2603
    email: forget about it http://web.torek.net/torek/index.html
    Reading email is like searching for food in the garbage, thanks to spammers.
    Chris Torek, Feb 4, 2005
    #11
    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. jimjim
    Replies:
    16
    Views:
    822
    Jordan Abel
    Mar 28, 2006
  2. Replies:
    4
    Views:
    1,229
    Fred Zwarts
    Jul 2, 2009
  3. A
    Replies:
    7
    Views:
    625
  4. , India

    pointer to an array vs pointer to pointer

    , India, Sep 20, 2011, in forum: C Programming
    Replies:
    5
    Views:
    439
    James Kuyper
    Sep 23, 2011
  5. arnuld

    pointer vs pointer to pointer

    arnuld, Jun 11, 2012, in forum: C Programming
    Replies:
    4
    Views:
    440
    Ben Bacarisse
    Jun 11, 2012
Loading...

Share This Page