复制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
相关产品推荐
相关产品推荐

