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

当num_samples2=252时,这段C语言代码为何触发无限循环?

为什么这段C代码会触发无限循环?

咱们先看你贴的代码片段:

if (num_samples2 == 252) { 
    char buffer[1024]; 
    char* p = buffer; 
    for(int a = 1; a < num_samples2 - 6; a = a + 6){ 
        p += sprintf(p, "%f,",data_samples[a]); 
        p += sprintf(p, "%f,",data_samples[a+1]); 
        p += sprintf(p, "%f,",data_samples[a+2]); 
        p += sprintf(p, "%f,",data_samples[a+3]); 
        p += sprintf(p, "%f,",data_samples[a+4]); 
        p += sprintf(p, "%f",data_samples[a+5]); 
    } 
}

核心原因是栈缓冲区溢出引发的未定义行为,意外篡改了循环相关变量,最终导致无限循环,具体拆解如下:

  • 理论循环次数与实际缓冲区不匹配:当num_samples2=252时,循环条件是a < 252-6=246,a从1开始每次加6,正常来说循环会执行40次左右(最后一次a=241,下一次a=247就不满足条件退出)。但你定义的buffer只有1024字节,每次循环要写入6个double类型的格式化字符串——随便一个123.456789,这样的字符串就占10个字符,一次循环至少写60多字节,40次下来总需求超过2400字节,远远超出buffer的容量上限。
  • 栈溢出篡改循环变量:buffer是栈上的局部数组,栈内存布局里,循环变量a、甚至num_samples2如果是局部变量的话,通常位于buffer的高地址侧。当sprintf不管不顾地往buffer外写数据时,就会覆盖这些变量:
    • 如果把a的值改成远小于246的数(比如被溢出的数据冲成1),循环条件会永远满足,自然无限运行;
    • 如果把num_samples2改得特别大,num_samples2-6也会随之变大,a永远追不上这个值,循环也停不下来。

这种情况属于C语言里的未定义行为,溢出后的表现不一定每次都完全一致,但无限循环是很常见的结果。

给你几个解决思路:

  • 换成更安全的snprintf,它能限制写入的字节数,从根源避免溢出;
  • 提前计算好所需的缓冲区大小,确保能装下所有输出内容;
  • 或者用malloc动态分配足够大的缓冲区。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 06:29:40