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

如何通过指针读取memcpy拷贝的struct结构体数据

问题根源

你触发访问异常的核心原因是memcpy的用法完全错误:

  • memcpy第一个参数是目标内存的起始地址,你传入了&pc也就是指针变量pc自身的内存地址,相当于把结构体t的二进制内容直接覆盖到了pc这个指针变量本身的存储区域,最终pc变成了指向非法地址的野指针,后续无论是用cout输出pc还是强制转成结构体指针访问,都会触发非法内存访问异常。

正确实现方案

你要实现的「用char类型缓存存储结构体内存、再恢复回结构体」的需求,正确写法如下:

#include <iostream>
#include <cstring>
#include <cstdint>

struct af {
    bool a;
    uint8_t b;
    uint16_t c;
};

int main() {
    af t;
    t.a = true;
    t.b = 3;
    t.c = 20;

    // 1. 申请足够存储结构体的char类型内存,让pc指向这块有效内存
    char buf[sizeof(af)] = {0};
    char* pc = buf;
    // 把结构体内容拷贝到pc指向的内存区域,而非覆盖pc本身的值
    memcpy(pc, &t, sizeof(t));

    // 2. 打印内存内容:不能直接cout << pc,char*默认会被当作C字符串处理,会越界
    std::cout << "结构体内存字节内容(十六进制):";
    for(int i=0; i<sizeof(af); i++) {
        std::cout << std::hex << (uint16_t)(uint8_t)pc[i] << " ";
    }
    std::cout << std::dec << std::endl;

    // 3. 恢复内容到新结构体
    af tt;
    memcpy(&tt, pc, sizeof(af));
    std::cout << "恢复后的结构体值:a=" << tt.a << ", b=" << (uint16_t)tt.b << ", c=" << tt.c << std::endl;

    // 如果需要用堆内存避免栈大小限制,可以用以下写法,使用完记得释放内存
    // char* pc = new char[sizeof(af)];
    // memcpy(pc, &t, sizeof(af));
    // ... 业务逻辑
    // delete[] pc;

    return 0;
}

注意事项

  • 不要用af* tt = (af*)(pc);强制指针类型转换的方式读取结构体内容:这种写法违反C++的严格别名规则,属于未定义行为。用memcpy把缓存内容拷贝到同类型结构体变量再访问是标准兼容的安全做法。
  • 只有*可平凡复制(TriviallyCopyable)*类型的结构体才能用memcpy直接拷贝内存,你当前定义的af结构体符合要求,如果后续添加了自定义构造函数、虚函数、非平凡拷贝构造函数等,就不能用这种方式操作。
  • 跨场景使用内存拷贝时要注意结构体内存对齐问题,不同编译器、编译选项的对齐规则可能不同,跨平台传输时建议手动指定对齐规则,避免结构体大小不一致导致拷贝错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 16:24:03