我想有一个函数,它分配一个2D数组,其中一个维度是固定的,并使用指向数组指针的指针将分配的内存提供给调用者。
例如,function()
会返回一个2D图像,其中行size
是固定的,但行的number
是在函数内确定的。
使用C99 VLA语法定义数组,因此我可以在函数内部和外部访问图像作为普通的2D数组image[y][x]
。
我认为function()
大部分是正确编写的,但我不知道如何在main(数组声明)中编写代码。在任何情况下我都无法访问函数外部的图像,我遇到分段错误,编译器抱怨。
我不希望有一个指针数组,应该有一个malloc()
和free()
,所有分配的内存应该是连续的。
#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);
}
我正在使用clang
和gcc
进行编译并获得下一个警告:
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.
实际上我的问题比给定的例子(list [i] [y][x]
)有一个维度,但应该应用相同的解决方案。
答案 0 :(得分:-1)
我假设您的要求是:
代码可能如下所示:
#include <stdlib.h>
void init(int rows, int cols, unsigned arr[rows][cols]) // same as "unsigned (*arr)[cols]"
{
for (int r = 0; r < rows; ++r)
for (int c = 0; c < cols; ++c)
arr[r][c] = r*c;
}
void func(int *p_rows, int cols, unsigned (**p_arr)[][cols])
{
*p_rows = 7;
*p_arr = malloc( sizeof(unsigned[*p_rows][cols]) );
if ( !*p_arr )
exit(EXIT_FAILURE);
// Possible to initialize here but it makes for more readable code to use a separate function
// (**p_arr)[2][3] = 5;
init(*p_rows, cols, **p_arr);
}
int main()
{
int cols = 7;
int rows;
unsigned (*p_arr)[][cols];
func(&rows, cols, &p_arr);
// Could do this here instead of calling init() from func()
init(rows, cols, *p_arr);
(*p_arr)[2][3] = 5;
// Optional - allow simpler access syntax
unsigned (*arr)[cols] = (void *)p_arr;
init(cols, rows, arr);
arr[2][3] = 5;
}
NB。如果您为获取rowcount而不是进行分配,那么它将简化代码。它还会简化代码以返回分配的指针,而不是使用out-parameter。