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

