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;
}
multidimensional array faulting
-
05-07-2023 - |
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.
Solution 2
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
}