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

C语言可变参数函数字符串拼接循环异常触发段错误咨询

问题背景

在树莓派4(Pi4)的FreeBSD arm64环境下测试C代码时遇到异常行为,已知当前逻辑存在更规范的实现方式,当前阶段目标为先跑通基础功能。
存在问题的可变参数字符串拼接函数代码如下:

#include <stdlib.h> 
#include <stdint.h> /* uints */
#include <string.h> /* char */
#include <stdio.h> /* printf*/
#include <stdarg.h> /* 处理可变数量参数 */

char* combineString(int num, ...) {
    
    char* finalStr;

    finalStr = calloc(600, sizeof(char));

    va_list vaList;
    
    /* 初始化可变参数列表 */
    va_start(vaList, num);

    printf("%i\n", num);

    for (int x = 0; x < num; num++) {

        char* str = va_arg(vaList, char*);

        strcat(finalStr, str);

        printf("%s\n", finalStr);
    }

    va_end(vaList);

    return finalStr;

}

异常表现

传入参数num=2指定待拼接字符串数量为2时,函数实际循环了5次而非预期的2次,num参数的设计作用为标识传入的可变参数总个数。
调用代码如下:

combineString(2, "f", "chartypehere");

实际运行输出:

2
f
fchartypehere
fchartypehere
fchartypehere
fchartypeherechartypehere

输出中chartypehere被重复拼接,不符合仅循环2次的预期。使用gcc编译后通过gdb调试触发如下段错误:

Program received signal SIGSEGV, Segmentation fault.
Address not mapped to object.
strcat (s=<optimized out>, append=<optimized out>) at /usr/src/lib/libc/string/strcat.c:46
46      /usr/src/lib/libc/string/strcat.c: No such file or directory.

初步判断异常属于未定义行为引发的巧合现象,但无法定位代码中具体的错误写法。

根因分析

核心错误是for循环的递增变量写错:

  • 循环语句写为for (int x = 0; x < num; num++),每次循环执行的是num++,循环变量x始终保持初始值0,永远满足x < num的判断条件,循环根本不会在执行2次后自动终止。
  • 可变参数列表仅传入了2个字符串指针,循环超出实际参数个数后继续调用va_arg读取参数属于标准未定义行为:程序会把栈上相邻内存的任意值当作char*指针解析,要么读到非法内存地址触发strcat访问未映射内存段,抛出你看到的SIGSEGV段错误;要么巧合读到之前传入的字符串常量地址,就会出现重复拼接chartypehere的现象。
修复方案

将for循环的递增操作从num++修改为x++即可修复循环次数异常的问题,修正后的循环代码如下:

for (int x = 0; x < num; x++) {
    char* str = va_arg(vaList, char*);
    strcat(finalStr, str);
    printf("%s\n", finalStr);
}

注意:当前实现给finalStr固定分配600字节空间,如果后续传入的待拼接字符串总长度超过599字节(需预留1字节存放字符串终止符\0),会触发缓冲区溢出,同样属于未定义行为。等基础功能跑通后,可以优化为先遍历计算所有待拼接字符串的总长度,再按需分配对应大小内存的实现,规避溢出风险。

内容的提问来源于stack exchange,提问作者CoN

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 12:42:17