C语言 从函数 c 返回二维数组的正确方法
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13390541/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
correct way to return two dimensional array from a function c
提问by Lior
I have tried this but it won't work:
我试过这个,但它不起作用:
#include <stdio.h>
int * retArr()
{
int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
return a;
}
int main()
{
int a[3][3] = retArr();
return 0;
}
I get these errors:
我收到这些错误:
Error 3 error C2075: 'a' : array initialization needs curly braces
4 IntelliSense: return value type does not match the function type
错误 3 错误 C2075:'a':数组初始化需要花括号
4 IntelliSense:返回值类型与函数类型不匹配
What am I doing wrong?
我究竟做错了什么?
回答by justin
A struct is one approach:
结构是一种方法:
struct t_thing { int a[3][3]; };
then just return the struct by value.
然后只需按值返回结构。
Full example:
完整示例:
struct t_thing {
int a[3][3];
};
struct t_thing retArr() {
struct t_thing thing = {
{
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
}
};
return thing;
}
int main(int argc, const char* argv[]) {
struct t_thing thing = retArr();
...
return 0;
}
The typical problem you face is that int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};in your example refers to memory which is reclaimed after the function returns. That means it is not safe for your caller to read (Undefined Behaviour).
您面临的典型问题是,int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};在您的示例中,指的是在函数返回后回收的内存。这意味着您的调用者阅读(未定义行为)是不安全的。
Other approaches involve passing the array (which the caller owns) as a parameter to the function, or creating a new allocation (e.g. using malloc). The struct is nice because it can eliminate many pitfalls, but it's not ideal for every scenario. You would avoid using a struct by value when the size of the struct is not constant or very large.
其他方法包括将数组(调用者拥有的)作为参数传递给函数,或创建新的分配(例如使用malloc)。该结构体很好,因为它可以消除许多陷阱,但它并不适用于所有场景。当结构的大小不是恒定的或非常大时,您将避免按值使用结构。
回答by Jagadeesh Pulamarasetti
We can solve it by using Heap memory / memory allocating using stdlib :
我们可以通过使用堆内存/使用 stdlib 分配内存来解决它:
Allocating memory using stdlib can be done by malloc and calloc.
creating array:
使用 stdlib 分配内存可以通过 malloc 和 calloc 来完成。
创建数组:
is for allocating 5 rows.int ** arr=( int * * ) malloc ( sizeof ( int * ) * 5 );
is for allocating 5 columns in each "i" row.arr[i]=(int *)malloc(sizeof(int)*5);- Thus we created arr [ 5 ] [ 5 ].
用于分配 5 行。int ** arr=( int * * ) malloc ( sizeof ( int * ) * 5 );
用于在每个“i”行中分配 5 列。arr[i]=(int *)malloc(sizeof(int)*5);- 因此我们创建了 arr [ 5 ] [ 5 ]。
returning array:
返回数组:
return arr;
return arr;
We just need to send that pointer which is responsible for accessing that array like above.
我们只需要像上面一样发送负责访问该数组的指针。
#include<stdio.h>
#include<stdlib.h>
int **return_arr()
{
int **arr=(int **)malloc(sizeof(int *)*5);
int i,j;
for(i=0;i<5;i++)//checking purpose
{
arr[i]=(int *)malloc(sizeof(int)*5);
for(j=0;j<5;j++)
{
arr[i][j]=i*10+j;
}
}
return arr;
}
int main()
{
int **now;
now=return_arr();
int i,j;
for(i=0;i<5;i++)
{
for(j=0;j<5;j++)
{
printf("%d ",now[i][j]);
}
printf("\n");
}
return 0;
}
回答by John Bode
Several issues:
几个问题:
First of all, you cannot initialize an array from a function call; the language definition simply doesn't allow for it. An array of charmay be initialized with a string literal, such as
首先,您不能从函数调用中初始化数组;语言定义根本不允许这样做。char可以用字符串字面量初始化一个数组,例如
char foo[] = "This is a test";
an array of wchar_t, char16_t, or char32_tmay be initialized with a wide string literal, but otherwise the initializer must be a brace-enclosed list of values.
wchar_t, char16_t, or的数组char32_t可以使用宽字符串文字进行初始化,但否则初始化程序必须是括号括起来的值列表。
Secondly, you have a type mismatch; except when it is the operand of the sizeofor unary &operators, or is a string literal being used to initialize another array in a declaration, an expression of type "N-element array of T" will be converted to an expression of type "pointer to T", and the value of the expression will be the address of the first element;
其次,您的类型不匹配;除非它是sizeof或 一元运算&符的操作数,或者是用于在声明中初始化另一个数组的字符串文字,否则“N 元素数组T”类型的表达式将转换为“指向T”类型的表达式, 表达式的值将是第一个元素的地址;
In the function retArr, the type of ain the expression is "3-element array of 3-element array of int"; by the rule above, this will be converted to an expression of type "pointer to 3-element array of int", or int (*)[3]:
在函数中retArr,a表达式中的类型为“三元数组的三元数组int”;根据上述规则,这将被转换为“指向 3 元素数组的指针”类型的表达式int,或者int (*)[3]:
int (*retArr())[3]
{
int a[3][3] = ...;
return a;
}
but as Brendan points out, once retArrexits ano longer exists; the pointer value that is returned winds up being invalid.
但正如 Brendan 指出的那样,一旦retArr退出a不再存在;返回的指针值最终无效。
回答by machoota
#include <stdio.h>
int** retArr()
{
static int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
return a;
}
int main()
{
int** a = retArr();
return 0;
}
You could also specify the returned variable as static. You also must declare the variable a in main as just int** (and not specify the dimensions).
您还可以将返回的变量指定为静态。您还必须将 main 中的变量 a 声明为 int** (而不指定维度)。
回答by Brendan
For this:
为了这:
int * retArr() {
int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
return a;
}
The array has local scope and is destroyed as soon as you exit the function. This means that return a;actually returns a dangling pointer.
该数组具有局部作用域,并在您退出函数后立即销毁。这意味着return a;实际上返回了一个悬空指针。
To fix this, put the array in global scope, or use malloc()and copy the array into the allocated space.
要解决此问题,请将数组置于全局范围内,或使用malloc()数组并将其复制到分配的空间中。
回答by VectorVortec
In the example given by the OP, it is the easiest to put the array on the stack. I didn't test this but it would be like this.
在OP给出的示例中,将数组放在堆栈上是最简单的。我没有测试这个,但它会是这样的。
#include stdio.h
#include stdio.h
void retArr(a[][3]) {
a[0][0] = 1; a[0][1] = 2; a[0][2] = 3;
a[1][0] = 4; a[1][1] = 5; a[1][2] = 6;
a[2][0] = 7; a[2][1] = 8; a[2][2] = 9;
}
main() {
int a[3][3];
retArr(a);
}
Yeah, this doesn't "return" the array with the return function, but I would suppose that wasn't the intent of the question. The array, a[][], does get loaded, and the loaded a[][] is available in main after retArr() is called, nothing is overwritten.
是的,这不会使用返回函数“返回”数组,但我认为这不是问题的意图。数组 a[][] 确实被加载,并且在调用 retArr() 后,加载的 a[][] 在 main 中可用,没有任何内容被覆盖。
回答by djechlin
Needs to return int**, not int.
需要返回int**,没有int。

