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

C语言写入结构体到void指针时结构体首元素值异常问题

问题原因

你的读写逻辑都存在下标偏移错误,直接导致第一个成员变量读取异常:

  • 写入时:你用dataObject[0]存数据长度,实际载荷需要从dataObject[1]开始存储,共objSize字节,对应输入结构体的0~objSize-1字节。但你的循环从i=1开始读取输入结构体的inputObject[i],直接漏掉了输入结构体的第0个字节(即testingInt1的第一个字节),且循环只拷贝了objSize-1个字节,数据没拷全。
  • 读取时:需要把dataObject[1]开始的objSize个字节拷贝到返回内存的0~objSize-1位置,但你的循环从i=1开始写返回内存dataToReturn[i],返回内存的第0个字节完全没被赋值,是malloc申请到的未初始化脏值——这个脏值刚好是0x50(十进制80),和后续三个0字节组合成int值80,就是你看到的错误结果。

第二个成员testingInt2能返回正确值是巧合:它在结构体中偏移4字节,你错误拷贝的字节刚好覆盖了它在返回结构体中的对应内存位置。

修正后的代码
#include <stdio.h>
#include <stdlib.h> // 补充exit函数需要的头文件
#include <malloc.h>

typedef struct dataBlock {
    void* dataObject;
} DataBlock;

typedef struct testingStruct {
    int testingInt1;
    int testingInt2;
} TestObject;

void dataWriter(DataBlock *dataBlock, void* inputObject, int objSize) {
    if (objSize > 255) {
        printf("Error. Maximum 255 Bytes of data can be stored.\n");
        exit(0);
    }
    dataBlock->dataObject = malloc(objSize+1);
    // 存长度时转unsigned char,避免有符号char导致长度为负的问题
    ((unsigned char*)dataBlock->dataObject)[0] = (unsigned char)objSize;
    // 修正下标:输入结构体从0开始拷贝,写到dataObject的i+1位置
    for (int i = 0; i < objSize; ++i) {
        ((char*)dataBlock->dataObject)[i+1] = ((char*)inputObject)[i];
    }
}

void* dataGetter(DataBlock *dataBlock) {
    // 先取出存储的长度,转unsigned char避免符号问题
    int objSize = (unsigned char)((char*)dataBlock->dataObject)[0];
    void* dataToReturn = malloc(objSize);
    // 修正下标:从dataObject的i+1位置读,写到返回内存的i位置
    for (int i = 0; i < objSize; ++i) {
        ((char*)dataToReturn)[i] = ((char*)dataBlock->dataObject)[i+1];
    }
    return dataToReturn;
}

int main() {
    TestObject *testObject = malloc(sizeof(TestObject));
    testObject->testingInt1 = 74;
    testObject->testingInt2 = 49;

    DataBlock *dataBlockToStore = malloc(sizeof(DataBlock));
    dataWriter(dataBlockToStore, testObject, sizeof(TestObject));

    TestObject *testObjectCpy = dataGetter(dataBlockToStore);
    printf("%d\n", testObjectCpy->testingInt1); // 正常输出74
    printf("%d\n", testObjectCpy->testingInt2); // 正常输出49

    // 实际使用时记得逐一free所有malloc申请的内存,避免内存泄漏

    return 0;
}
额外说明
  • 补充了stdlib.h头文件,exit函数需要该头文件声明,否则可能出现编译警告或运行异常。
  • 存储/读取长度时转换为unsigned char,避免当char默认为有符号类型时,长度大于127出现负数的问题,匹配你最大支持255字节的设计。

内容的提问来源于stack exchange,提问作者Giancarlo Metitieri

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 22:21:27