malloc分配数组的函数参数传递问题:段错误原因及方法正确性咨询
关于C语言指针数组传递的问题
我用malloc创建了一个数组:
int *array = (int *) malloc(10 * sizeof(int));
我希望在函数中使用该数组,并且能在main函数中修改数组的值,因此定义了如下函数:
void func(int **array);
我尝试了两种实现方法:
第一种方法(可正常运行)
void func(int **arr){ arr[0][0] = 100; arr[0][1] = 200; } int main(){ int *arr = (int*) malloc(10 * sizeof(int)); func(&arr); printf("arr[0] = %d\narr[1] = %d\n", arr[0], arr[1]); return 0; }
第二种方法(无法运行,出现段错误)
typedef int* intarr; void func(intarr *arr){ *arr[0] = 100; *arr[1] = 200; } int main(){ intarr arr = (int*) malloc(10 * sizeof(int)); func(&arr); printf("arr[0] = %d\narr[1] = %d\n", arr[0], arr[1]); return 0; }
我的问题:
- 第二种方法为何会出现段错误?
- 第一种方法是否正确?
- 你使用的是什么工具?
问题解答
1. 第二种方法出现段错误的原因
核心是运算符优先级问题:[]的优先级高于*,代码里的*arr[0]会被编译器解析为*(arr[0]),而非预期的(*arr)[0]。
在第二种方法中,arr是intarr*类型(本质是int**):
arr[0]等价于*(arr+0),也就是传入的&arr(main函数中数组指针变量的地址),*arr[0]取这个地址里的值,也就是main中arr指向的malloc数组首地址,这一步操作合法;- 但
*arr[1]会被解析为*(arr+1),也就是&arr的下一个内存地址,这个地址属于未定义的内存区域,对其进行赋值操作直接触发了段错误。
正确写法应该修改为(*arr)[0] = 100;和(*arr)[1] = 200;,先解引用得到main里的数组指针,再访问数组元素。
2. 第一种方法是正确的
第一种方法中,arr是int**类型:
arr[0]等价于*(arr+0),也就是对传入的&arr解引用,得到main函数中的数组指针arr;arr[0][0]等价于(*arr)[0],直接访问数组的第一个元素,赋值操作合法,能正确修改数组内容,运行结果符合预期。
3. 使用的工具
我基于C语言标准规则和运算符优先级规则分析代码问题,验证时可使用GCC编译器编译运行代码,复现问题并验证修复结果。
内容的提问来源于stack exchange,提问作者suiciyom
相关产品推荐
相关产品推荐

