Search code examples
arrayscpointerspointer-to-array

confused about pointer syntax when defining type in C


In some starter code we have:

 /**
 * RGBTRIPLE
 *
 * This structure describes a color consisting of relative intensities of
 * red, green, and blue.   
 *
 * Adapted from http://msdn.microsoft.com/en-us/library/aa922590.aspx.
 */
 typedef struct
{
    BYTE  rgbtBlue;
    BYTE  rgbtGreen;
    BYTE  rgbtRed;
} __attribute__((__packed__))
RGBTRIPLE;

and in our main program we have:

RGBTRIPLE(*image)[width] = calloc(height, width * sizeof(RGBTRIPLE));

I'm confused about (*image)

If I was to define a pointer to a RGBTRIPLE I thought I would use:

RGBTRIPLE *image[width] = ....

Is that the same as:

RGBTRIPLE(*image)[width] = ....   ?

Solution

  • RGBTRIPLE *image[width]; 
    

    Is an array of pointers to RGBTRIPLE, this array will have width number of elements. Each pointer in this array is capable of pointing to a RGBTRIPLE object, that makes it possible to have a 2D array when you have several of these objects per row.

    The allocation is messier because you would need to allocate the array of pointers themselves and then each row for which each pointer would be pointing to, and later deallocate the memory in reverse order.


    RGBTRIPLE(*image)[width];
    

    Is a pointer to array of RGBTRIPLE, this array must have width number of elements, that being the case you can use it to point to a 2D array with any number of rows as long as it has width number of columns.

    This is a better way of implenting a 2D array because it facilitates the allocation and deallocation.

    This works by allowing it to move the pointer in blocks of width size of bytes by incrementing it, in practice it let's you "jump" to the next row by incrementing the pointer once.

    For example, an array of 6 of width and 2 of height:

                 +-----------+
    image[0] ->  |0|1|2|3|4|5|
                 +-----------+
                 |5|4|3|2|1|0|
                 +-----------+
                          
                  
                          +-> image[0][4]
                          |
                 +-----------+
                 |0|1|2|3|4|5|
                 +-----------+
    image[1] ->  |5|4|3|2|1|0|
                 +-----------+
                          |
                          +-> image[1][4]
    

    The expression:

    RGBTRIPLE(*image)[width] = calloc(height, width * sizeof(RGBTRIPLE));
    

    could be better, I would use a safer method:

    RGBTRIPLE(*image)[width] = calloc(height, sizeof *image);