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

复制char*到char*[]数组时触发Segmentation fault问题排查

为什么你的strcpy会触发Segmentation Fault?

嘿,这个段错误的原因其实很典型——你没给指针数组里的每个指针分配有效的内存空间!

先看你的代码里的char *output[20];:这是一个能存20个char*指针的数组,但这些指针一开始都是未初始化的野指针,指向的是内存里的随机位置。当你用strcpy(*(output+i), token);的时候,相当于直接往一个随机的内存地址写数据,操作系统当然会阻止你,直接抛出段错误。

两种修复方案

方案1:动态分配内存(灵活适配任意长度的token)

既然strtok返回的是原字符串里的片段,我们需要为每个token单独分配足够的内存来存储它的内容,步骤如下:

#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h> // 要包含malloc和free的头文件

int main() {
    char input[20];
    char *output[20];
    char *token = NULL;
    int count = 0,i=0;
    printf("Enter the input string\n");
    // 注意:scanf("%s")会在空格处停止读取,如果要读整行建议用fgets
    scanf("%s",input);
    token = strtok(input,",");
    while(NULL != token) {
        // 为当前token分配内存:长度+1是为了存储字符串结束符'\0'
        output[i] = malloc(strlen(token) + 1);
        // 一定要检查malloc是否成功,避免内存分配失败的情况
        if (output[i] == NULL) {
            perror("Failed to allocate memory");
            // 先释放已经分配的内存再退出,避免泄漏
            for (int j=0; j<i; j++) {
                free(output[j]);
            }
            return 1;
        }
        strcpy(output[i], token);
        i++;
        count++;
        token = strtok(NULL,",");
    }

    // 这里可以加代码验证输出,比如打印每个token
    for (int j=0; j<count; j++) {
        printf("Token %d: %s\n", j+1, output[j]);
    }

    // 程序结束前记得释放所有动态分配的内存,避免内存泄漏
    for (int j=0; j<count; j++) {
        free(output[j]);
    }
    return 0;
}

方案2:用二维字符数组(适合token长度固定的场景)

如果能确定每个token的长度不会超过某个值,可以直接把output定义成二维字符数组,这样每个元素都是一个现成的字符缓冲区,不需要手动分配内存:

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

int main() {
    char input[20];
    char output[20][20]; // 20个长度为20的字符数组,每个能存19个字符+1个'\0'
    char *token = NULL;
    int count = 0,i=0;
    printf("Enter the input string\n");
    scanf("%s",input);
    token = strtok(input,",");
    while(NULL != token) {
        // 直接复制到二维数组的对应行里
        strcpy(output[i], token);
        i++;
        count++;
        token = strtok(NULL,",");
    }

    // 验证输出
    for (int j=0; j<count; j++) {
        printf("Token %d: %s\n", j+1, output[j]);
    }

    return 0;
}

⚠️ 注意:这个方案的局限性是如果token长度超过19,会导致缓冲区溢出,所以只适合已知输入长度的场景。

额外提醒:关于输入读取

你的代码里用scanf("%s", input);,它会在遇到空格、换行或制表符时停止读取。如果你需要读取包含空格的整行输入,建议换成fgets:

fgets(input, sizeof(input), stdin);
// 去掉fgets读取到的末尾换行符(如果有的话)
size_t len = strlen(input);
if (len > 0 && input[len-1] == '\n') {
    input[len-1] = '\0';
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:22:54