如何将C语言中二维数组指针赋值给数组?技术问询
问题分析与可行实现方案
原代码核心问题
- 局部数组返回指针导致悬空指针:
testArrData函数内的int arr[n][m]是栈上的局部变量,函数执行完毕后栈帧会被销毁,这块内存会被系统回收或覆盖,返回它的指针会指向无效内存,后续访问会触发未定义行为。 - 数组无法直接通过指针赋值:C语言中数组名是不可修改的左值,不能直接将指针赋值给数组变量,比如
arr = testArrData(m,n);这类写法是非法的。
可行实现方案
方案一:调用者提供目标数组作为参数
这种方式无需动态分配内存,直接在调用者的数组中填充数据,从根源避免悬空指针问题。
#include <stdlib.h> #include <time.h> // 填充测试数据到调用者传入的二维数组 void testArrData(int m, int n, int arr[][m]) { // 仅初始化一次随机数生成器 static int rand_inited = 0; if (!rand_inited) { srand((unsigned int)time(NULL)); rand_inited = 1; } for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { arr[i][j] = rand() % 10; } } } int main() { int m = 3, n = 4; int arr[m][n]; int arrT[n][m]; // 填充测试数据到arr testArrData(m, n, arr); // 矩阵转置逻辑 for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { arrT[j][i] = arr[i][j]; } } return 0; }
方案二:动态分配二维数组内存
如果需要函数返回二维数组,可以使用堆内存动态分配,注意使用完毕后手动释放内存,避免泄漏。
#include <stdlib.h> #include <time.h> // 动态分配并填充二维数组,返回指向数组的指针 int** testArrData(int m, int n) { // 初始化随机数生成器 static int rand_inited = 0; if (!rand_inited) { srand((unsigned int)time(NULL)); rand_inited = 1; } // 分配行指针数组 int** arr = (int**)malloc(m * sizeof(int*)); if (!arr) return NULL; // 分配每行内存并填充数据 for (int i = 0; i < m; i++) { arr[i] = (int*)malloc(n * sizeof(int)); if (!arr[i]) { // 分配失败时回滚已分配内存 for (int k = 0; k < i; k++) free(arr[k]); free(arr); return NULL; } for (int j = 0; j < n; j++) { arr[i][j] = rand() % 10; } } return arr; } int main() { int m = 3, n = 4; int** arr = testArrData(m, n); if (!arr) return 1; // 分配转置后的数组内存 int** arrT = (int**)malloc(n * sizeof(int*)); if (!arrT) { // 释放原数组内存 for (int i = 0; i < m; i++) free(arr[i]); free(arr); return 1; } for (int j = 0; j < n; j++) { arrT[j] = (int*)malloc(m * sizeof(int)); if (!arrT[j]) { // 回滚已分配内存 for (int k = 0; k < j; k++) free(arrT[k]); free(arrT); for (int i = 0; i < m; i++) free(arr[i]); free(arr); return 1; } } // 矩阵转置逻辑 for (int i = 0; i < m; i++) { for (int j = 0; j < n; j++) { arrT[j][i] = arr[i][j]; } } // 释放所有动态分配的内存 for (int i = 0; i < m; i++) free(arr[i]); free(arr); for (int j = 0; j < n; j++) free(arrT[j]); free(arrT); return 0; }
额外注意事项
- 使用
rand()前必须调用srand()初始化随机数种子,否则每次运行会生成完全相同的随机序列。 - 动态分配内存后必须检查返回值是否为
NULL,避免空指针访问。 - 动态分配的内存必须手动释放,否则会造成内存泄漏。
内容的提问来源于stack exchange,提问作者Korneliusz93
相关产品推荐
相关产品推荐

