如何通过指针读取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
相关产品推荐
相关产品推荐

