You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助: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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:22:25