C语言:访问函数参数传递的字符数组元素及内存错误排查
如何访问函数参数中的字符数组元素 & 代码错误修复
一、访问函数参数里的字符数组元素
在C语言里,传递字符数组给函数通常有两种常见场景,对应不同的访问方式:
- 场景1:直接传递字符数组(或字符指针)
如果函数参数是char arr[]或者char *arr(数组名传递时会自动退化为指针),你可以直接用下标arr[i]或者指针解引用*(arr + i)来访问第i个元素。比如:void printArr(char *arr, int len) { for (int i = 0; i < len; i++) { printf("%c ", arr[i]); // 下标访问方式 // 也可以写成 printf("%c ", *(arr + i)); 指针偏移方式 } } - 场景2:传递指向字符指针的指针(
char **)
这种情况一般是想在函数内部给外部的字符指针分配内存(就像你的代码场景),此时要访问数组元素,得先通过*s拿到指向数组的实际指针,再用下标或指针方式访问:(*s)[i]或者*( (*s) + i )。核心是先解引用拿到数组指针,再操作元素。
二、你的代码错误分析与修复
错误原因
你的代码里,问题出在*(s[i]) = 'a';这一行:
s是char **类型,也就是指向char*的指针。s[i]等价于*(s + i),当i=0时,s[0]就是*s(你malloc出来的数组指针),这时候赋值没问题;但i=1时,s[1]是*(s + 1),相当于把s指针往后移动一个char*的大小,指向的是完全未知的内存(因为s只是指向main里单个char*变量的指针,并没有第二个char*元素),所以对*(s[i])赋值就会触发内存访问错误(EXC_BAD_ACCESS)。
另外还有个隐藏问题:你malloc了len个char,但没加字符串结束符'\0',用printf("%s", *s)时会越界读取内存,因为%s要求字符串以'\0'结尾。
修复后的代码
#include <stdio.h> #include <stdlib.h> void test(char ** s, int len) { // 多分配一个字节存字符串结束符'\0' *s = (char *)malloc(sizeof(char) * (len + 1)); if (*s == NULL) { // 必须检查malloc是否成功 perror("malloc failed"); return; } int i; for(i = 0; i < len; i++) { (*s)[i] = 'a'; // 正确访问:先拿到数组指针,再用下标操作元素 // 也可以写成 *( (*s) + i ) = 'a'; 效果一致 } (*s)[len] = '\0'; // 添加字符串结束符 printf("%s\n", *s); } int main() { char * s; test(&s, 3); free(s); // 记得释放内存,避免内存泄漏 return 0; }
关键修复点
- 把
*(s[i]) = 'a';改成(*s)[i] = 'a';:(*s)是你malloc出来的字符数组指针,(*s)[i]就是数组的第i个元素。 - malloc时多分配一个字节,用来存储
'\0',保证printf("%s")能正常工作。 - 添加malloc失败的检查,这是C语言编程的良好习惯。
- 在main函数里调用
free(s),释放分配的内存,避免内存泄漏。
内容的提问来源于stack exchange,提问作者Yos
相关产品推荐
相关产品推荐

