求助:C语言中tokenize函数无法修改char指针数组问题排查
你的字符串分割函数问题排查与修复
看起来你在实现tokenize函数修改字符指针数组时遇到了预期外的问题,我帮你拆解代码里的几个关键错误:
1. 未初始化的指针num2是核心问题
在process_cmd里,你声明了int *num2;但没有让它指向任何有效的内存地址——它现在只是一个随机的野指针。当tokenize函数执行*numTokens = argc - 1;时,相当于往一块未知的内存写数据,这会触发未定义行为:可能程序直接崩溃,可能输出奇怪的数字,甚至偶尔看似正常但埋下严重隐患。
2. 无用的返回类型声明
你把tokenize的返回类型定义成了void**,但函数内部根本没有return语句。C语言虽然允许这种写法,但完全没必要——你根本没用到这个返回值,直接把返回类型改成void会让代码更清晰规范。
3. 潜在的数组越界风险
你在process_cmd里用了char *temp[20];,这个数组最多能存20个指针(包括最后用来标记结束的NULL)。如果分割出来的token数量超过19个,就会越界写入内存,同样会引发各种不可预料的问题。如果你的业务场景里token数量不会这么多,这个问题暂时不明显,但最好加上边界检查防患未然。
修复后的完整代码
我把这些问题都修正了,还做了一些细节优化:
#include <stdio.h> #include <string.h> // 将返回类型改为void,因为不需要返回任何值 void tokenize(char **argv, char *line, int *numTokens, char *delimiter) { int argc = 0; // 添加边界检查,避免数组越界 while (argc < 19) { // 预留一个位置放结尾的NULL char *token = (argc == 0) ? strtok(line, delimiter) : strtok(NULL, delimiter); if (token == NULL) break; argv[argc++] = token; } argv[argc] = NULL; // 直接用当前argc索引放NULL,逻辑更清晰 *numTokens = argc; // 这里直接赋值argc,不需要再减1 } void process_cmd(char *cmdline){ char *temp[20]; // 声明一个实际的int变量,让num2指向它 int token_count; int *num2 = &token_count; tokenize(temp, cmdline, num2, "|"); // 输出前先检查指针是否有效,避免访问空指针崩溃 if (temp[0] != NULL) printf("%s\n", temp[0]); if (temp[1] != NULL) printf("%s\n", temp[1]); printf("Token数量:%d\n", *num2); } // 测试用例 int main() { char test_cmd[] = "ls -l | grep .txt | wc -l"; process_cmd(test_cmd); return 0; }
修复点说明
- 给
num2绑定了实际的int变量token_count,让tokenize里的赋值操作能写到正确的内存地址,解决了野指针的问题。 - 调整了
tokenize的返回类型,去掉了无用的void**声明。 - 增加了数组边界检查,防止token过多导致越界。
- 优化了
NULL赋值和token计数的逻辑,让代码更易读。 - 输出时增加了空指针检查,避免当token数量不足时程序崩溃。
内容的提问来源于stack exchange,提问作者hang99
相关产品推荐
相关产品推荐

