从函数c返回二维数组的正确方法
我试过这个,但它不起作用:
#include 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; }
我收到这些错误:
错误3错误C2075:’a’:数组初始化需要花括号
4 IntelliSense:返回值类型与function类型不匹配
我究竟做错了什么?
结构是一种方法:
struct t_thing { int a[3][3]; };
然后按值返回结构。
完整示例:
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; }
你面临的典型问题是int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
在您的示例中指的是在函数返回后回收的内存。 这意味着调用者读取(Undefined Behavior)是不安全的。
其他方法涉及将数组(调用者拥有的)作为参数传递给函数,或者创建新的分配(例如使用malloc
)。 结构很好,因为它可以消除许多陷阱,但它并不适合每种情况。 当结构的大小不是常量或非常大时,您将避免使用struct by value。
#include 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; }
您还可以将返回的变量指定为static。 您还必须将main中的变量a声明为int **(而不是指定维度)。
几个问题:
首先,您无法从函数调用初始化数组; 语言定义根本不允许它。 可以使用字符串文字初始化char
数组,例如
char foo[] = "This is a test";
可以使用宽字符串文字初始化wchar_t
, char16_t
或char32_t
数组,但否则初始化程序必须是括号括起的值列表。
其次,你有一个类型不匹配; 除非它是sizeof
或一元&
运算符的操作数,或者是一个字符串文字用于初始化声明中的另一个数组,“N元素数组T
”的表达式将转换为类型“的表达式”指向T
“的指针,表达式的值将是第一个元素的地址;
在函数retArr
,表达式中a
的类型是“3元素数组的3元素数组”; 根据上面的规则,这将转换为“指向3元素数组的int
”或int (*)[3]
类型的表达式:
int (*retArr())[3] { int a[3][3] = ...; return a; }
但正如布兰登指出的那样,一旦retArr
退出就不再存在; 返回的指针值无效。
我们可以使用stdlib使用堆内存/内存分配来解决它:
使用stdlib分配内存可以通过malloc和calloc完成。
创建数组 :
-
int ** arr=( int * * ) malloc ( sizeof ( int * ) * 5 );
用于分配5行。
-
arr[i]=(int *)malloc(sizeof(int)*5);
用于在每个“i”行中分配5列。
- 因此我们创建了arr [5] [5]。
返回数组:
-
return arr;
我们只需要发送负责访问该数组的指针,如上所述。
#include #include 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; }
为了这:
int * retArr() { int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}}; return a; }
该数组具有本地范围,并在退出函数后立即销毁。 这意味着return a;
实际上返回一个悬空指针。
要解决此问题,请将数组放在全局范围内,或使用malloc()
并将数组复制到已分配的空间中。
需要返回int**
,而不是int
。