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

C语言动态内存分配程序中总线错误的修复方案咨询

修复中间名缩写程序的总线错误与逻辑问题

以下是你的代码存在的核心问题及修复方案:

问题分析

  1. 修改只读字符串字面量:main中直接传递字符串字面量"Artur José Bastos Costa"给abrevia,而strtok会修改输入字符串。字符串字面量存储在只读内存区域,修改会触发总线错误。
  2. 内存分配未包含终止符:malloc(strlen(full_name) * sizeof(char))没有为字符串终止符'\0'预留空间,导致内存越界。
  3. 原字符串被破坏:第一次用strtok遍历full_name后,原字符串已被分割截断,后续复制nomeCopy只能得到第一个名字,无法处理完整姓名。
  4. 字符串操作逻辑错误:手动通过下标赋值的方式会覆盖字符(比如先写.再写 ,导致.丢失),且重复处理了第一个名字。

修复后的代码

#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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 02:57:35