confused about pointer syntax when defining type in C

246 Views Asked by At

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] = ....   ?
2

There are 2 best solutions below

6
anastaciu On BEST ANSWER
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);
0
dbush On

These are not the same.

RGBTRIPLE *image[width]

This denotes an array of size width whose elements are of type RGBTRIPLE *, i.e. it is an array of pointers.

RGBTRIPLE(*image)[width]

This is a pointer to an array of size width whose members are of type RGBTRIPLE.

Both can be used to implements a 2D array, but in different ways. If you used the former declaration, you would have to allocate the extra dimension as follows:

int i;
for (i=0; i<width; i++) {
    image[i] = calloc(height, sizeof(RGBTRIPLE));
}