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

C语言实现字符串拆分单词(禁用strdup)程序触发段错误求助

字符串拆分C代码段错误修复

我写了一段C语言代码,用来把字符串拆分成单词,要求不能用strdup函数,必须用malloc和strcpy实现。目标是当char *cmd = "Hello world baby"时,让argv[0] = "Hello"、argv[1] = "world"、argv[2] = "baby"。

原代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define buf_size 128

int main() {
    
    char *argv[16];
    memset(argv, 0, sizeof(argv));
    int words = 0;

    char *cmd = "Hello world baby";
    unsigned int len = strlen(cmd);
    int start = 0;
    for(unsigned int i = 0; i <= len; i++){
        if(cmd[i] == ' ' | cmd[i] == '\0'){
            ++words;
            char *w = (char *)malloc(sizeof(char)*(i-start) + 1);
            strcpy(w, cmd + start);
            w[i-start] = '\0';
            argv[i] = w;
            start = i + 1;
        }
    }

    for(int i = 0; i < words; i++){
    printf("%s\n", argv[i]);
    free(argv[i]);
    }
    return 0;
}

期望输出:

Hello
world
baby

但程序运行到printf时触发了段错误。

错误原因

  1. 索引赋值错误:这是触发段错误的核心原因。原代码将拆分出的单词赋值给argv[i],这里的i是循环到的字符位置(比如第一个空格在第5位,就赋值给argv[5]),但后续printf循环遍历的是0到words-1(即0、1、2),这三个位置的argv元素都是初始的空指针,printf访问空指针直接引发段错误。
  2. 逻辑运算符误用:判断条件中使用了按位或|,正确应该用逻辑或||。虽然当前测试用例下该错误未直接触发问题,但会导致逻辑判断不符合预期(例如某些字符按位或后会被误判为分隔符)。

修正后的代码

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define buf_size 128

int main() {
    
    char *argv[16];
    memset(argv, 0, sizeof(argv));
    int words = 0;
    int idx = 0; // 新增索引变量,用于正确给argv数组赋值

    char *cmd = "Hello world baby";
    unsigned int len = strlen(cmd);
    int start = 0;
    for(unsigned int i = 0; i <= len; i++){
        // 将按位或|替换为逻辑或||
        if(cmd[i] == ' ' || cmd[i] == '\0'){
            // 跳过连续空格,避免生成空单词
            if(i == start){
                start = i + 1;
                continue;
            }
            ++words;
            // 分配内存,计算单词长度+1用于存储结束符
            char *w = (char *)malloc(sizeof(char) * (i - start) + 1);
            if(w == NULL){ // 检查内存分配是否成功
                perror("malloc failed");
                // 释放已分配的内存,避免泄漏
                for(int j = 0; j < idx; j++){
                    free(argv[j]);
                }
                return 1;
            }
            // 安全复制单词内容,并手动添加字符串结束符
            strncpy(w, cmd + start, i - start);
            w[i - start] = '\0';
            argv[idx++] = w;
            start = i + 1;
        }
    }

    for(int i = 0; i < words; i++){
        printf("%s\n", argv[i]);
        free(argv[i]);
    }
    return 0;
}

额外优化说明

  • 连续空格处理:遇到连续空格时跳过,不会生成空单词,避免无效的内存分配和输出。
  • 内存分配失败检查:添加malloc失败的判断,此时会释放已分配的内存并退出程序,防止内存泄漏。
  • 安全字符串复制:将strcpy替换为strncpy,避免复制超出分配内存范围的内容,提升代码安全性。

内容的提问来源于stack exchange,提问作者Seil Lee

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 07:20:53