Reputation: 700
I'm working on an assignment for class and having some issues with assigning values to an unsigned int **
variable that is in an object. For some reason, I can not assign it with malloc stating that there is an error with assignment to expression with array type
. I'm not sure what this means, I have tried to use directly malloc it to image->pixmap
, but have the same issue. This happens in both methods.
P.S. As this is an assignment I can NOT change the structs/object definitions, otherwise I would have.
I will do my best to explain the pixmap
for PPMImage
as an example:
pixmap: Three height x width, 2-dimensional pixel arrays, for ’R’, ‘G’, ‘B’ values
height: image height (number of rows)
width: image width (number of columns)
pixmax: maximum pixel value of image
//p->pixmap[0]: ‘R’ pixmap array
//p->pixmap[1][7]: 8th row of pixels of ‘G’ pixmap array
//p->pixmap[2][4][10]: 11th pixel in 5th row of ‘B’ pixmap array
typedef struct {
unsigned int ** pixmap[3];
unsigned int height, width, pixmax;
} PPMImage;
PPMImage * new_ppmimage( unsigned int w, unsigned int h, unsigned int m )
{
PPMImage *image;
image = (PPMImage *) malloc(sizeof(PPMImage));
image -> height = h;
image -> width = w;
unsigned int ** tempArray = malloc(sizeof(unsigned int *)*h);
for(int i = 0;i < h; i++){
tempArray[i] = malloc(sizeof(unsigned int) *w);
}
// issue here
image -> pixmap = tempArray;
return NULL;
}
=======================================
typedef struct {
unsigned int ** pixmap;
unsigned int height, width;
} PBMImage;
PBMImage * new_pbmimage( unsigned int w, unsigned int h )
{
PBMImage *image;
image = (PBMImage *) malloc(sizeof(PBMImage));
image -> height = h;
image -> width = w;
// issue here
image -> pixmap = malloc(sizeof(unsigned int *)*h);
for(int i = 0;i < h; i++){
image -> pixmap[i] = malloc(sizeof(unsigned int) *w);
}
return NULL;
}
Upvotes: 1
Views: 133
Reputation: 67546
Your code will never work as you always return NULL not the allocated memory in the new_ppmimage
function.
If you cant change the types:
typedef struct {
unsigned int ** pixmap[3];
unsigned int height, width, pixmax;
} PPMImage;
PPMImage * new_ppmimage( unsigned int w, unsigned int h, unsigned int m )
{
PPMImage *image;
image = malloc(sizeof(*image));
if(image)
{
image -> height = h;
image -> width = w;
for(size_t i = 0; i < sizeof(image -> pixmap) / sizeof(image -> pixmap[0]); i++)
{
image -> pixmap[i] = malloc(h * sizeof(*image -> pixmap));
if(image -> pixmap)
{
for(unsigned hi = 0; hi < h; hi++)
{
image -> pixmap[i][hi] = malloc(w * sizeof(**image -> pixmap[i]));
if(!image -> pixmap[hi])
{
/* handle memory allocation error */
}
}
}
}
}
return image;
}
and the second one. See that there is almost no difference.
typedef struct {
unsigned int ** pixmap;
unsigned int height, width;
} PBMImage;
PBMImage * new_pbmimage( unsigned int w, unsigned int h)
{
PBMImage *image;
image = malloc(sizeof(*image));
if(image)
{
image -> height = h;
image -> width = w;
image -> pixmap = malloc(h * sizeof(*image -> pixmap));
if(image -> pixmap)
{
for(unsigned hi = 0; hi < h; hi++)
{
image -> pixmap[hi] = malloc(w * sizeof(**image -> pixmap));
if(!image -> pixmap[hi])
{
/* handle memory allocation error */
}
}
}
}
return image;
}
I would implement it using flexible array members and array pointers. Only one malloc
and free
are needed. Much more efficient as two levels of indirection are removed.
typedef struct {
size_t height, width, pixmax;
unsigned int pixmap[][3];
} PPMImage;
PPMImage * new_ppmimage( const size_t w, const size_t h, unsigned int m )
{
PPMImage *image;
image = malloc(sizeof(*image) + h * w * sizeof(image -> pixmap[0]));
if(image)
{
image -> height = h;
image -> width = w;
}
return image;
}
And simple usage:
unsigned int getPixelVal(PPMImage *image, const size_t x, const size_t y, const size_t index)
{
unsigned int (*pixel)[image -> width][3] = image -> pixmap;
return pixel[y][x][index];
}
Upvotes: 1
Reputation: 3812
This
unsigned int ** pixmap[3];
means that pixmap
is an array of size 3 containing values of the type "pointer to pointer to unsigned int". It is not possible to directly assign anything to an array type like this.
You probably want to do something like this:
image->pixmap[0] = tempArray;
This assigns tempArray
to the first element of pixmap
. Notice how the types of these match.
Repeat the allocation process to allocate memory for pixmap[1]
and pixmap[2]
as well.
Upvotes: 2