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

