char**数组赋值异常:C语言split函数多参数场景下的bug排查
问题根因
这完全是代码编写错误引发的未定义行为,核心有两处错误:
- 第一处:realloc扩容计算逻辑错误
sizeof(argv)获取的是指针变量自身的字节长度(64位系统为8字节、32位系统为4字节),而非当前argv数组已分配的总容量。你每次扩容都固定按sizeof(argv) + sizeof(char*)申请内存,意味着数组最大只能容纳2个char*元素,当参数数量超过2后,后续赋值操作都会发生堆缓冲区溢出,越界修改堆上的其他数据。你观察到的“给argv[i]赋值NULL反而修改了argv[0]”、参数超过4个时realloc报错,都是堆溢出后的典型表现。 - 第二处:字符串内存分配长度不足
calloc(strlen(token), sizeof(char))只分配了等于字符串有效长度的内存,没有预留存储字符串终止符\0的1字节空间,后续strcpy操作同样会发生内存越界。
修正后的代码
char **split(char string[], char *sep) { char *token = strtok(string, sep); char **argv = NULL; int i = 0; while (token != NULL) { // 每次扩容到i+2个元素:当前新增1个,+1留作终止NULL argv = realloc(argv, (i + 2) * sizeof(char*)); // 分配空间时+1存字符串终止符 argv[i] = malloc(strlen(token) + 1); strcpy(argv[i++], token); token = strtok(NULL, sep); } argv[i] = NULL; return argv; }
注:如果需要更高鲁棒性,可以额外加
realloc、malloc返回值为空的判断逻辑,避免空指针解引用。
你之前参数数量<=2时运行正常,属于未定义行为中“恰好未触发异常”的巧合,不代表代码逻辑正确。
内容的提问来源于stack exchange,提问作者bol'shoy
相关产品推荐
相关产品推荐

