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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 15:14:53