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

C语言字符串拼接函数realloc运行异常问题求助

你的代码存在以下核心问题:

  • strtok用法错误:首次调用传原字符串后,后续获取下一个单词需要给第一个参数传NULL,你循环中每次都传入原str会导致死循环,且永远只能拿到第一个单词
  • 指针值传递问题:addTo是一级指针,函数内部realloc修改的是局部指针副本的值,外部原指针不会同步更新,一旦realloc申请了新的内存地址,外部指针直接变成野指针;如果你的addTo初始是栈内存而非堆内存,realloc会直接抛出异常,因为realloc仅支持处理malloc/calloc/realloc申请的堆内存
  • 内存申请大小计算错误:仅计算了原字符串+新单词的长度,没有算上后续要拼接的#、@的长度,会发生缓冲区越界
  • 分隔符参数错误:" \0\n"中的\0会被识别为字符串结束符,实际strtok仅会把空格作为分隔符,换行符不会生效
  • 循环逻辑错误:while(str != NULL)的判断永远为真,只要str入参非空就会进入死循环
  • 多余#问题:每个单词拼接后都加#,会导致最后一个单词末尾多一个不必要的#

修复后的代码实现

// addTo需要传入二级指针,外部调用示例:char* dst = NULL; addStr(&dst, "test hello", 1);
void addStr(char** addTo, char* str, int on)
{
    if (str == NULL || addTo == NULL) return;

    // 首次调用strtok传原字符串,分隔符设为空格、换行
    char* temp = strtok(str, " \n");
    while (temp != NULL)
    {
        size_t original_len = *addTo ? strlen(*addTo) : 0;
        size_t temp_len = strlen(temp);
        // 计算需要的内存:原长度 + 新单词长度 + 可能加的#长度 + 最后可能加的@长度 + 结束符\0
        size_t new_size = original_len + temp_len + 2 + (on ? 1 : 0);
        // realloc自动处理*addTo为NULL的情况
        *addTo = (char*)realloc(*addTo, new_size * sizeof(char));
        if (*addTo == NULL) return; // 内存申请失败直接返回

        // 如果不是第一个单词,先拼#
        if (original_len > 0) {
            strcat(*addTo, "#");
        }
        strcat(*addTo, temp);

        // 取下一个单词
        temp = strtok(NULL, " \n");
    }

    // 最后加@
    if (on && *addTo != NULL) {
        strcat(*addTo, "@");
    }
}

注意事项

  • 外部调用时传入的目标指针初始可以设为NULL,如果是手动申请的初始内存,必须是堆内存
  • strtok会修改传入的str原字符串,如果不想修改原字符串,需要先拷贝一份再传入函数处理
  • 用完目标字符串后需要手动free释放内存,避免内存泄漏

内容的提问来源于stack exchange,提问作者יונתן אליהו

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 20:06:06