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

动态扩展char数组超31字符出现副作用及代码崩溃原因咨询

C字符串拼接代码的问题解答

我来帮你拆解这两个问题,结合你的代码和Valgrind检测结果逐一分析:

问题1:注释掉的*string[*used]=0的作用与段错误原因

代码原本的意图

这行代码是想给拼接后的字符串添加C语言字符串必需的'\0'终止符,这样后续用fprintf输出时,才能正确识别字符串的结束位置,避免读取越界的内存内容。

触发段错误的核心原因

问题出在C语言的运算符优先级上:数组下标[]的优先级高于解引用*,所以*string[*used]会被编译器解析为*(string[*used])。

  • string是char**类型(指向char*的指针),string[*used]相当于访问第*used个char*元素,但你的程序里string只指向了一个buffer指针(也就是只有string[0]是有效的)。
  • 当*used大于0时,string[*used]就是在访问超出合法范围的内存地址,属于非法内存访问,直接触发段错误。

正确的写法

如果要实现添加终止符的功能,需要给*string加上括号,确保先解引用得到buffer的指针,再访问对应下标:

(*string)[*used] = 0;

问题2:字符总数超过31出现副作用的原因

先看你代码里的内存分配逻辑:

char *buffer=(char*) malloc(sizeof(char));

你只给buffer分配了1字节的内存,但后续每次调用add_to_string时,直接用memcpy往buffer + *used的位置写数据——这完全是在越界写入未分配的内存区域,属于C语言中的未定义行为。

  • 当写入的字符较少时,可能刚好越界的内存还没被其他数据占用,程序看起来能“正常”运行;
  • 当字符总数超过一定长度(比如31),越界写入会覆盖堆上的其他数据(比如used变量的内容、malloc的元数据),甚至可能覆盖到栈上的缓存信息(比如fprintf的格式化字符串)。这就会导致程序出现各种奇怪的副作用,比如你看到的重复输出There are 14 argument(s) to process,本质就是内存被破坏后,fprintf读取到了错误的内容。

Valgrind的检测结果也直接点明了问题:

27291 Invalid write of size 1
27291 at 0x4C33B5B: memmove (vg_replace_strmem.c:1258)
27291 by 0x1088B2: add_to_string (tmp.c:9)
27291 Address 0x51f4091 is 0 bytes after a block of size 1 alloc'd

这段日志明确说明你在写入超出malloc分配的1字节内存之外的区域,属于非法操作。

简单修复思路

要解决这个问题,你需要在每次添加数据前检查当前buffer的容量是否足够,不够的话用realloc重新分配更大的内存(比如每次扩容为原来的2倍,或者预先计算所有参数的总长度一次性分配)。比如可以给add_to_string增加一个capacity参数跟踪当前buffer的容量,当*used + data_len >= capacity时,触发内存扩容。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:33:09