I would like to have a function which allocates a 2D array with one of the dimensions fixed and provides the allocated memory back to the caller using a pointer to an array pointer.
For example the function()
would return a 2D image, where the line size
is fixed but the number
of lines is determined inside the function.
The arrays are defined using C99 VLA syntax, so I can access the image as a normal 2D array image[y][x]
inside and outside the function.
I think function()
is written mostly correctly, but I do not know how to write the code in main (array declaration). In any case I can not access the image outside the function, I get a segmentation fault and the compiler complains.
I do not wish to have an array of pointers, there should be a single malloc()
and free()
and all allocated memory should be continuous.
#include <stdio.h>
#include <stdlib.h>
int function (size_t size, size_t *number, int unsigned (*image) [] [size]);
int function (size_t size, size_t *number, int unsigned (*image) [] [size]) {
size_t image_size;
*number = 9;
image_size = (*number) * size;
printf ("INSIDE malloc: number=%zu size=%zu image_size=%zu\n", *number, size, image_size); fflush(stdout);
image = (int unsigned (*) [] [size]) malloc (sizeof(int unsigned) * image_size);
printf ("INSIDE assign: number=%zu size=%zu\n", *number, size); fflush(stdout);
for (int unsigned l=0; l<*number; l++) {
for (int unsigned s=0; s<size; s++) {
(*image) [l] [s] = (l << 16) + s;
}
}
(*image) [0] [0] = 0xDEADC0DE;
printf ("INSIDE print: number=%zu size=%zu\n", *number, size); fflush(stdout);
for (int unsigned l=0; l<*number; l++) {
printf ("l=%u:", l);
for (int unsigned s=0; s<size; s++) {
printf (" %08x", (*image) [l] [s]);
}
printf ("\n");
}
return (0);
}
int main (int argc, char **argv) {
size_t size;
size_t number;
size = 5;
int unsigned (* image) [size];
printf ("TEST:\n"); fflush(stdout);
function (size, &number, &image);
fflush(stdout);
// printf ("OUTSIDE print: number=%zu size=%zu\n", number, size); fflush(stdout);
// for (int unsigned l=0; l<number; l++) {
// printf ("l=%u:", l);
// for (int unsigned s=0; s<size; s++) {
// printf (" %08x", (*image) [l] [s]);
// }
// printf ("\n");
// }
// free(image);
return (0);
}
I am compiling with clang
and gcc
and getting the next warning:
clang -o test test.c -g -std=c99
test.c:44:34: warning: incompatible pointer types passing 'unsigned int (**)[size]' to parameter of type 'unsigned int (*)[][*]' [-Wincompatible-pointer-types]
function (size, &number, &image);
^~~~~~
test.c:6:63: note: passing argument to parameter 'image' here
int function (size_t size, size_t *number, int unsigned (*image) [] [size]) {
^
1 warning generated.
Actually my problem has one dimension more than the given example (list [i] [y][x]
) but the same solution should apply.