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

C语言中将字符串转换为字符串数组时出现段错误求助

问题分析与修复方案

原代码核心问题

  • 未检查命令行参数是否传入,直接访问argv[1]会触发段错误
  • 字符串内存分配未预留\0空间:calloc(strlen(token), sizeof(char))缺少1字节,strcpy会越界
  • 循环逻辑错误:首次获取token后未判空就复制,后续循环先递增count再取token,token为NULL时仍执行内存操作引发崩溃
  • 最终输出循环起始位置错误,无法正确遍历数组

修复后的代码示例

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    // 检查命令行参数
    if (argc < 2) {
        fprintf(stderr, "请传入待分割的字符串\n");
        return EXIT_FAILURE;
    }

    int count = 0;
    // 复制argv[1],避免strtok_r修改原参数内容
    char *str = strdup(argv[1]);
    if (str == NULL) {
        perror("strdup失败");
        return EXIT_FAILURE;
    }

    char *token, *last;
    // 预分配指针数组空间
    char **arr_str = calloc(9999, sizeof(char*));
    if (arr_str == NULL) {
        perror("calloc失败");
        free(str);
        return EXIT_FAILURE;
    }

    // 首次分割字符串
    token = strtok_r(str, " ,", &last);
    while (token != NULL) {
        // 分配内存:strlen(token)+1 预留'\0'位置
        arr_str[count] = calloc(strlen(token) + 1, sizeof(char));
        if (arr_str[count] == NULL) {
            perror("calloc失败");
            // 释放已分配内存,避免泄漏
            for (int i = 0; i < count; i++) {
                free(arr_str[i]);
            }
            free(arr_str);
            free(str);
            return EXIT_FAILURE;
        }
        // 复制字符串到分配的内存
        strcpy(arr_str[count], token);
        printf("分割结果:%s\n", arr_str[count]);
        count++;
        // 继续分割剩余内容
        token = strtok_r(NULL, " ,", &last);
    }

    printf("------------\n");
    // 正序输出数组
    for (int i = 0; i < count; i++) {
        printf("%s ", arr_str[i]);
    }
    printf("\n");

    // 倒序输出数组
    printf("倒序输出:");
    for (int i = count - 1; i >= 0; i--) {
        printf("%s ", arr_str[i]);
    }
    printf("\n");

    // 释放所有内存
    for (int i = 0; i < count; i++) {
        free(arr_str[i]);
    }
    free(arr_str);
    free(str);

    return EXIT_SUCCESS;
}

关键实现要点

  • 内存分配规则:
    分割出的每个字符串必须分配strlen(token) + 1字节内存,C字符串以\0结尾,这1字节是必须的;用calloc会自动初始化内存为0,也可改用malloc(strlen(token)+1)后手动补\0,但calloc更安全。
  • 指针数组创建:
    先分配二级指针数组char **arr_str,每个元素为char*类型,指向分割后的字符串;若不确定token数量,可先预分配初始空间,后续用realloc动态扩容。
  • 内存安全注意:
    每次分配内存后必须检查是否成功;程序结束前释放所有分配的内存,避免泄漏;不要直接修改argv[1],先用strdup复制原字符串,因为strtok_r会修改原字符串内容。
  • 循环逻辑修正:
    先获取token并判空,再执行内存分配和复制,避免token为NULL时调用strlen引发崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 19:45:38