C语言缓冲区写入异常:生成二进制文件出现随机乱码问题
问题分析与修复方案
核心错误点
1. 误用memset填充整数
memset是按单个字节重复填充内存的工具,不能用来写入多字节整数。比如代码里的memset(memory, size, 4),会把前4个字节都填成size的低8位值(比如size=32时,每个字节都是0x20,也就是空格字符),完全不是我们要存储的uint32_t数值,直接导致头部的size、elementSize、lastIndex字段全错。
正确做法是直接通过指针赋值:
*(uint32_t*)memory = size; *(uint32_t*)(memory + 4) = elementSize; *(uint32_t*)(memory + 8) = numberOfElements - 1;
2. fwrite写入长度错误
sizeof(myIntegers)取的是指针的大小(32位系统4字节,64位8字节),不是malloc分配的整个内存块大小。这导致实际只写了前4/8字节的错误数据,后面的有效数组内容根本没写入文件,所以用xxd查看时看到的都是垃圾数据。
正确做法是从头部读取总长度再写入:
uint32_t totalSize = *(uint32_t*)myIntegers; fwrite(myIntegers, totalSize, 1, testfp);
修正后的完整代码
#include <stdio.h> #include <stdlib.h> #include <stdint.h> #include <string.h> /* Reference: (0 offset) uint32_t size; (+4 offset) uint32_t elementSize; (+8 offset) uint32_t lastIndex; (+12 offset) void* data */ void* create_pinned_array(uint32_t elementSize, uint32_t numberOfElements, size_t sizeOfData, void* data) { uint32_t size = sizeOfData + 12; void* memory = malloc(size); if (!memory) return NULL; // 增加内存分配失败检查 // 正确写入头部的uint32_t字段 *(uint32_t*)memory = size; *(uint32_t*)(memory + 4) = elementSize; *(uint32_t*)(memory + 8) = numberOfElements - 1; memcpy(memory + 12, data, sizeOfData); // 复制实际数据 return memory; } int main(void) { int randomList[5] = { 1, 6, 2, 9, 8 }; void* myIntegers = create_pinned_array(sizeof(int), 5, sizeof(randomList), randomList); if (!myIntegers) { perror("创建数组失败"); return 1; } FILE* testfp = fopen("testfile.bin", "wb"); if (!testfp) { perror("打开文件失败"); free(myIntegers); return 1; } // 从头部读取总大小,写入完整数据 uint32_t totalSize = *(uint32_t*)myIntegers; fwrite(myIntegers, totalSize, 1, testfp); fclose(testfp); free(myIntegers); return 0; }
验证效果
修正后运行程序,用xxd查看testfile.bin会得到正确内容:
- 前4字节是总大小32(小端序显示为
00000020) - 接下来4字节是int的大小4(
00000004) - 再接下来4字节是lastIndex4(
00000004) - 最后20字节是数组
{1,6,2,9,8}的二进制表示(小端序下为00000001 00000006 00000002 00000009 00000008)
内容的提问来源于stack exchange,提问作者Hexa
相关产品推荐
相关产品推荐

