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

CS50 Volume实验为何用单个buffer变量而非malloc或数组?

CS50 Lab #4 "Volume" 缓冲区变量用法疑问解答

问题代码

// TODO: Read samples from input file and write updated data to output file
int16_t buffer;
while (fread(&buffer, sizeof(int16_t), 1, input))
{
    buffer *= factor;
    fwrite(&buffer, sizeof(int16_t), 1, output);
}

疑惑点

该buffer变量分配在栈上,地址固定,无法像数组或堆指针那样索引。不解的是:fwrite为何能持续写入循环外声明的同一变量地址?该写法反复更新同一内存地址的值直至文件结束。能理解用int16_t buffer[];的情况,但为何该方案无需malloc也能正常工作且不触发段错误?


解答

  1. 同一地址重复读写的合理性
    栈上的buffer是单个int16_t类型变量,它的内存地址在声明后确实固定不变,但这完全不影响循环中的读写操作:
  • 每次fread都会把输入文件里的下一个音频样本(占2字节)写入到buffer的内存地址中,直接覆盖掉变量里之前的旧值;
  • 修改buffer *= factor后,fwrite再把当前buffer里的新值写到输出文件,全程操作的都是这个变量的当前值,而非固定的旧数据。只要每次读写的字节数(sizeof(int16_t))和变量类型匹配,重复读写同一地址完全合法。
  1. 无需数组或malloc的原因
    这个场景下我们只需要逐个处理单个音频样本,单个int16_t变量的内存空间(2字节)已经足够容纳一个样本,根本不需要数组或者堆内存:
  • 栈上分配的buffer在整个while循环的作用域内都是有效的,每次循环只是更新它的值,不会出现内存越界或失效的情况;
  • 只有当我们需要一次性批量处理多个样本(比如一次读1024个)时,才需要用数组或者malloc申请连续内存来存储多个样本。这里单样本处理的逻辑,用单个栈变量就足够完成任务,自然不会触发段错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 03:05:26