如何返回2D数组?

发布于 2025-02-04 16:46:46 字数 502 浏览 3 评论 0原文

我正在寻找一种创建2D数组并返回的有效方法,通常我会制作一系列指针,为每个指针分配内存,然后返回** ptr。我一直在寻找另一种方法,因为那时我必须释放分配的每个记忆。

我在线阅读,您可以分配一个2D数组:int( *arr)[n] = malloc(sizeof *arr *i); 其中PTR是一个指针,指的是arr [n]的地址。

当我尝试返回ARR时,从以下函数:int *array_of_smallest(int count);
我得到:警告:从不兼容的指针类型'int( *)[n]'[ - wincompatible-pointer-types]的分配

给 'int *'然后返回它,我只返回一个1D数组。

我认为我正在混合不同的概念并使自己感到困惑。

有了一系列的指针,我没有问题,但是我想要一种更简单的方法来创建一个2D数组,也更容易释放,但是我无法从功能中返回该数组。

I was searching for an efficient way to create a 2D array and return it, usually I make an array of pointers, allocate memory for each pointer, and return an **ptr. I was looking for another way to do it because then I have to free every single memory allocated.

I was reading online that you can allocate a 2D array like this: int (*arr)[n] = malloc( sizeof *arr * i );
In which ptr is a pointer, pointing to the adress of arr[n].

When I try to return arr, from the following function: int *array_of_smallest(int count);
I get: warning: assignment to ‘int *’ from incompatible pointer type ‘int (*)[n]’ [-Wincompatible-pointer-types]

If I initialise another pointer and point it to array, then return it, I'm only returning a 1D array.

I think I'm mixing diferent concepts and confusing myself.

With an array of pointers I don't have a problem, but I wanted a simplier way to create a 2D array, also easier to free, but I'm not being able to return that array from my function.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

笑叹一世浮沉 2025-02-11 16:46:47

您声明了变量修改类型int( *)[n]的指针。

int (*arr)[n] = malloc( sizeof *arr * i );

那是声明器中使用的变量n不是整数常数表达式。

在这种情况下,函数应具有返回类型void *。可以像

void * array_of_smallest(int count)
{
    int (*arr)[n] = malloc( sizeof *arr * i );
    //...
    return arr;
} 

在呼叫者中一样声明,您将

int ( *arr )[n] = array_of_smallest( count );

在此声明中编写n的值必须与函数中使用的值相同。

如果要使用类似的整数常数表达式

int (*arr)[2] = malloc( sizeof *arr * 2 );

,则该函数声明看起来像是这样

int ( * array_of_smallest(int count) )[2];

,或者您可以在函数声明之前引入typedef名称

typedef int Array[2];

,在这种情况下,该函数看起来像

Array * array_of_smallest(int count);

You declared a pointer of the variable modified type type int ( * )[n].

int (*arr)[n] = malloc( sizeof *arr * i );

That is the variable n used in the declarator is not an integer constant expression.

In this case the function should have the return type void *. And it can be declared like

void * array_of_smallest(int count)
{
    int (*arr)[n] = malloc( sizeof *arr * i );
    //...
    return arr;
} 

In the caller you will write

int ( *arr )[n] = array_of_smallest( count );

In this declaration the value of n must be the same as used within the function.

If to use an integer constant expression like

int (*arr)[2] = malloc( sizeof *arr * 2 );

then the function declaration will look like

int ( * array_of_smallest(int count) )[2];

Or you can introduce a typedef name before the function declaration like

typedef int Array[2];

and in this case the function will look like

Array * array_of_smallest(int count);
等风来 2025-02-11 16:46:47

返回数组的基本问题是,在文件范围内不可能声明可变修饰的类型(例如指向VLA的指针)。

问题的原因可以解释为如下。您的代码的行为或多或少类似:

typedef int T[n];

T* array_of_smallest(int count) { ... }

不幸的是,由于两个原因,定义这种类型t是不可能的:

  • n通常在文件范围内看不见,除非它是n的全局变量
  • 评估,需要在文件范围上执行代码,该代码 forbidden

workarounds

  1. return void*如其他< a href =“ https://stackoverflow.com/a/72516342/4989451”>答案。

  2. 将指针传递给“副参考”样式的VLA,作为指向数组指针的指针

void array_of_smallest(int count, int (**p)[n]) {
 ...
 *p = arr;
}
  1. 将指针返回指向不完整的数组类型的int []。不可能返回不完整的类型,但是可以将指针返回到不完整类型的指针:
int (*array_of_smallest(int count))[] { ... }

或在type> typeof Extension(C23中的功能)的帮助下有点清洁器

typeof(int[]) *array_of_smallest(int count) { ... }

,并将其如void*案例:

int ( *arr )[n] = array_of_smallest( count );

此解决方案为元素类型提供类型检查,但是它仅适用于二维数组。

  1. 将指针包装到结构中,并使用宏来重建其类型在客户端:
typedef struct {
  int rows, cols;
  void* data;
} Arr2D;

Arr2D array_of_smallest(int count) {
  ...
  return (Arr2D) { .rows = i, .cols = n, .data = arr };
}

#define ARR2D_DEF_VIEW(view, arr2d) int (*view)[(arr2d).cols] = (arr2d).data

... usage ...

Arr2D arr = array_of_smallest(42);
ARR2D_DEF_VIEW(view, arr);

... do stuff with view[i][j]
}

另外,请使用typeof扩展名来推断VLA视图的类型,而不是在宏中声明它:

#define ARR2D_VIEW_TYPE(arr2d) typeof(int(*)[(arr2d).cols])

...

Arr2D arr = array_of_smallest(42);
ARR2D_VIEW_TYPE(arr) view = arr.data;

The fundamental issue with returning the array is that it is not possible to declare Variably-Modified Type (like a pointer to VLA) at the file scope.

The reason of the problem can be explained as follow. Your code behaves more or less like this:

typedef int T[n];

T* array_of_smallest(int count) { ... }

Unfortunately, defining such a type T is not possible because of two reasons:

  • n is usually not visible at file scope, except if it was a global variable
  • evaluation of n would require code execution at file scope which is forbidden

Workarounds

  1. Return void* as described in other answer.

  2. Pass a pointer to VLA in "by-reference" style, as a pointer to a pointer to array

void array_of_smallest(int count, int (**p)[n]) {
 ...
 *p = arr;
}
  1. Return a pointer to incomplete array type of int[]. It is not possible to return incomplete types but it is possible to return a pointer to incomplete types:
int (*array_of_smallest(int count))[] { ... }

or a bit cleaner with a help of typeof extension (feature in C23)

typeof(int[]) *array_of_smallest(int count) { ... }

And use it as in the void* case:

int ( *arr )[n] = array_of_smallest( count );

This solution provides type-checking for the element type, however it works only for 2-dimensional arrays.

  1. Wrap the pointer into a structure and use a macro to reconstruct its type on the client side:
typedef struct {
  int rows, cols;
  void* data;
} Arr2D;

Arr2D array_of_smallest(int count) {
  ...
  return (Arr2D) { .rows = i, .cols = n, .data = arr };
}

#define ARR2D_DEF_VIEW(view, arr2d) int (*view)[(arr2d).cols] = (arr2d).data

... usage ...

Arr2D arr = array_of_smallest(42);
ARR2D_DEF_VIEW(view, arr);

... do stuff with view[i][j]
}

Alternatively, use typeof extension to infer the type of VLA view rather than declare it in a macro:

#define ARR2D_VIEW_TYPE(arr2d) typeof(int(*)[(arr2d).cols])

...

Arr2D arr = array_of_smallest(42);
ARR2D_VIEW_TYPE(arr) view = arr.data;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文