C语言动态内存分配程序中总线错误的修复方案咨询
修复中间名缩写程序的总线错误与逻辑问题
以下是你的代码存在的核心问题及修复方案:
问题分析
- 修改只读字符串字面量:
main中直接传递字符串字面量"Artur José Bastos Costa"给abrevia,而strtok会修改输入字符串。字符串字面量存储在只读内存区域,修改会触发总线错误。 - 内存分配未包含终止符:
malloc(strlen(full_name) * sizeof(char))没有为字符串终止符'\0'预留空间,导致内存越界。 - 原字符串被破坏:第一次用
strtok遍历full_name后,原字符串已被分割截断,后续复制nomeCopy只能得到第一个名字,无法处理完整姓名。 - 字符串操作逻辑错误:手动通过下标赋值的方式会覆盖字符(比如先写
.再写,导致.丢失),且重复处理了第一个名字。
修复后的代码
#include <stdio.h> #include <string.h> #include <stdlib.h> char* abrevia(const char* full_name){ // 先复制原字符串到可写内存,避免修改只读字面量 char* name_copy = malloc(strlen(full_name) + 1); if (!name_copy) return NULL; strcpy(name_copy, full_name); // 第一步:统计名字数量 int num_names = 0; char* token = strtok(name_copy, " "); while (token != NULL) { num_names++; token = strtok(NULL, " "); } free(name_copy); // 用完释放 // 重新复制原字符串用于分割处理 char* process_copy = malloc(strlen(full_name) + 1); if (!process_copy) return NULL; strcpy(process_copy, full_name); // 分配结果内存:原字符串长度足够容纳缩写后的内容(中间名变短) char* abbreviation = malloc(strlen(full_name) + 1); if (!abbreviation) { free(process_copy); return NULL; } abbreviation[0] = '\0'; // 初始化空字符串 token = strtok(process_copy, " "); int current_idx = 0; while (token != NULL) { if (current_idx == 0) { // 第一个名字直接复制 strcpy(abbreviation, token); } else if (current_idx == num_names - 1) { // 最后一个名字直接拼接 strcat(abbreviation, " "); strcat(abbreviation, token); } else { // 中间名:首字母 + . + 空格 strcat(abbreviation, " "); strncat(abbreviation, token, 1); strcat(abbreviation, "."); } current_idx++; token = strtok(NULL, " "); } free(process_copy); return abbreviation; } int main(){ char* abr = abrevia("Artur José Bastos Costa"); if (abr) { printf("%s\n", abr); free(abr); } return 0; }
关键修改说明
- 使用
const char*接收输入:明确输入字符串不可修改,同时在函数内部将其复制到可写内存后再使用strtok。 - 两次独立复制原字符串:第一次用于统计名字数量,第二次用于实际处理,避免原字符串被破坏。
- 正确初始化结果字符串:将
abbreviation初始化为空字符串,确保strcat等函数正常工作。 - 分情况处理名字:第一个名字直接复制,中间名只取首字母加
.,最后一个名字完整拼接,避免重复处理。 - 添加内存分配失败检查:避免空指针操作,提升程序健壮性。
内容的提问来源于stack exchange,提问作者Duarte Pereira
相关产品推荐
相关产品推荐

