Question

So, I need to generate an array, the struct is set up like so:

struct image
{
    int height, width;
    unsigned char (**data)[3];
};
typedef struct image image_t;

And I am using a function to allocate and initially set all the positions to 0 values (the three slots it actually uses)

image_t create_new_image(int height, int width)
{
 int i, j;
 image_t ret;
 ret.data = malloc(height + 5);
 for (i = 0; i < height; i++)
     ret.data[i] = malloc(width + 5);
 for (i = 0; i < height; i++)
 {
     for (j = 0; j < width; j++) //hit every node
     {
        ret.data[i][j][0] = 0;
        ret.data[i][j][1] = 0;
        ret.data[i][j][2] = 0;
     }
 }
 ret.height = height;
 ret.width = width;
 check_nulls(ret);
 return ret;
}

GDB gives the following:

Breakpoint 2, create_new_image (height=20, width=21) at ansilib.c:28
28      for (i = 0; i < height; i++)
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0x0000000100001292 in create_new_image (height=20, width=21) at ansilib.c:33
33              ret.data[i][j][1] = 0;
(gdb) p i
$1 = 4
(gdb) p j
$2 = 0
(gdb) p ret.data[0]
$3 = (unsigned char (*)[3]) 0x1001038c0
(gdb) p ret.data[1]
$4 = (unsigned char (*)[3]) 0x1001038e0
(gdb) p ret.data[2]
$5 = (unsigned char (*)[3]) 0x100103900
(gdb) p ret.data[3]
$6 = (unsigned char (*)[3]) 0x100103920
(gdb) p ret.data[4]
$7 = (unsigned char (*)[3]) 0x0
(gdb) p ret.data[5]
$8 = (unsigned char (*)[3]) 0x0

Can somebody help me understand what I am doing wrong? I havn't dealt with multidimensional run-time allocated arrays very much, so it is probably just the way it is allocated, but i'm pretty clueless.

Was it helpful?

Solution 2

image_t create_new_image(int height, int width){
    int i, j;
    image_t ret;
    ret.data = malloc(height*sizeof(*ret.data));
    for (i = 0; i < height; i++)
        ret.data[i] = malloc(width*sizeof(**ret.data));
    for (i = 0; i < height; i++){
        for (j = 0; j < width; j++){
            ret.data[i][j][0] = 0;
            ret.data[i][j][1] = 0;
            ret.data[i][j][2] = 0;
        }
    }
    ret.height = height;
    ret.width = width;
    check_nulls(ret);
    return ret;
}

OTHER TIPS

Your malloc calls are incorrect. The malloc function expects the number of bytes, not the number of object (and I have no idea what + 5 is supposed to indicate).

If you use the idiom ptr = malloc(N * sizeof *ptr) then it makes things easy:

ret.data = malloc(height * sizeof *ret.data);
for (i = 0; i < height; i++)
    ret.data[i] = calloc(width, sizeof *ret.data[i]);

Then the rest of your code is OK as far as I can see.

Using calloc instead of malloc means that you don't need to loop through setting everything to 0. It doesn't matter which way around the arguments are for calloc.

I guess you want to create RGB or YUB image data.

The problem is this line :

ret.data = malloc(height + 5);

Because you declared

unsigned char (**data)[3];

you can't assign memory to ret.data. It is already allocated as 3-element array.

Try

for(int i=0; i<3; i++) {
     ret.data[i] = malloc() // for height
     for(every line)
          ret.data[i][j] = malloc() // for width
          // and set all elements to zero
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top