在C语言中如何使用malloc分配的内存作为fread的缓冲区
问题原因与修复方案
核心错误点
- 调用
fseek跳到文件末尾计算大小后,没有把文件指针重置回文件起始位置,后续fread从文件末尾开始读取,自然读不到任何内容。 fread第一个参数传参错误,audio本身已经是指向malloc分配内存的指针,不需要再加取地址符&。添加取地址符后相当于传入了存储audio指针变量自身的栈内存地址,内容会被写入栈区域而非malloc分配的堆内存,同时还会触发内存越界问题。
正确实现步骤
- 计算完文件大小后,调用
rewind(input)或者fseek(input, 0L, SEEK_SET)将文件指针重置到文件起始位置 - 修改
fread的第一个参数为audio即可 - 建议补充所有操作的返回值判断,避免异常场景下出现崩溃或者逻辑错误
修复后的完整示例代码
#include <stdint.h> #include <stdio.h> #include <stdlib.h> int main() { // 打开二进制文件必须用rb模式,避免Windows平台下换行符自动转换导致内容异常 FILE* input = fopen("你的音频文件路径", "rb"); if (input == NULL) { perror("打开文件失败"); return 1; } // 计算文件大小 fseek(input, 0L, SEEK_END); long audioSize = ftell(input); if (audioSize < 0) { perror("获取文件大小失败"); fclose(input); return 1; } // 重置文件指针到开头,核心修复点1 rewind(input); typedef uint8_t BYTE; BYTE* audio = (BYTE*) malloc(audioSize); if (audio == NULL) { perror("内存分配失败"); fclose(input); return 1; } // 修正后的fread调用,核心修复点2:去掉audio前的& size_t readCount = fread(audio, sizeof(BYTE), audioSize, input); if (readCount != audioSize) { printf("读取文件不完整,预期读取%ld字节,实际读取%zu字节\n", audioSize, readCount); free(audio); fclose(input); return 1; } // 这里添加你的业务处理逻辑 // 用完后释放资源,避免泄漏 free(audio); fclose(input); return 0; }
额外注意事项
- 打开二进制文件必须使用
rb模式,Windows平台下如果用默认的r模式会自动转换换行符,导致读取的内容和实际文件大小不一致 - 所有IO操作、内存分配操作都建议加返回值判断,方便快速定位异常问题
- 不再使用的堆内存和文件指针要及时释放,避免内存泄漏和文件句柄泄漏
内容的提问来源于stack exchange,提问作者FatSumo
相关产品推荐
相关产品推荐

