So I've been trying to store a PPM file in a program to be manipulated, I successful stored everything up to the colors, I've made progress on the colors.
During asking a question on stack overflow ( For loop stops for no reason ) I was convinced that my method was a bit shoddy, however I don't understand the reasoning for using the follow:
COLOR (*colors)[width] = malloc( sizeof(COLOR[height][width]) );
can someone break down exactly what this line of code is doing and explain what type it is. So I can store it in a struct and successful return it.
Example: previously I used pointers to pointers, where I allocated a height and for each pointer I allocated a width. This means that for each pointer I could create a color, increment it along the width until Im at the end, then reset the pointer and increment the height and loop. After I got the full image I return it to store it in the follow:
typedef struct {
char code[CODE_LENGTH];
COMMENT *commentPPM;
int width, height, max;
COLOR **colorValues;
} PPM;
using:
ppmFile->colorValues = getColors(fd, ppmFile->width, ppmFile->height);
and
typedef struct{
int red, green, blue;
} COLOR;
COLOR * getNextColor(FILE *fd);
COLOR **getColors(FILE *fd, int width, int height){
printf("\nentered get colors");
COLOR **colors = malloc(sizeof(COLOR*)*height);
printf("\nallocated %d space height",height);
int i,j;
for(i = 0; i < height; i++, colors++){
*colors = malloc(sizeof(COLOR)*width);
printf("\nallocated %d space width",width);
for(j = 0; j < width; j++, *(colors++)){
printf("\nlooping through to get the colors for point (%d,%d)", j,i);
//*colors = getNextColor(fd);
}
*colors -= width;
printf("\nmoved the pointer for *colors back %d spaces",width);
}
colors -= height;
printf("\nmoved the pointer for colors back %d spaces",height);
return colors;
}
In order to understand this, you need to first understand the concepts:
Given that already you know what the above is, then the most formally proper way to do this is to declare an array pointer to a 2D VLA:
COLOR (*colors)[height][width];
And when you call malloc, you tell it to allocate enough space for such an array:
malloc( sizeof(COLOR[height][width]) )
You would then end up with
colors = malloc( sizeof(COLOR[height][width]) );
However, since colors
in this example is an array pointer, you would have to de-reference it each time you wish to access the array:
(*colors)[i][j] = something;
This syntax is not practical and also hard to read.
Therefore, you can use another trick and skip the inner-most dimension when you declare the array pointer. Instead of a pointer to a 2D array, you could skip the inner-most dimension and just declare an array pointer to a 1D array:
COLOR (*colors)[width]
but use this with the very same malloc call as before. Because now you can take advantage of array pointer arithmetic:
colors[i][j] = something;
Which essentially means, "in my array-of-arrays, give me array number i
, item number j
".
It works for the same reason as int* x = malloc(sizeof(int[n])); ... x[i] = something;
int* x = malloc(sizeof(int[n])); ... x[i] = something;
works, which of course gives you int
number i
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.