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

使用memcpy拷贝含std::string的结构体失败问题咨询

问题分析与解决方案

一、为什么会出现这种现象?

你代码里的核心问题有两个:

  1. memcpy的拷贝长度参数错误
    你用sizeof(&ValuesOut)作为拷贝长度,这是取指针变量的大小——在64位系统下指针固定为8字节。而你的Test1结构体实际大小是48字节(int占4字节+内存对齐填充4字节+std::string内部成员占40字节),所以memcpy只拷贝了前8字节,刚好覆盖int Value的内容,std::string Text的部分完全没被拷贝,这就是ValuesOut.Text为空的原因。
  2. 即使拷贝长度正确,memcpy也不适合拷贝含std::string的结构体
    std::string不是POD(普通旧数据类型),它内部持有指向堆内存的指针来存储实际字符串内容。memcpy是浅拷贝,只会复制string对象的内部指针,不会复制指针指向的堆内存。这会导致两个string对象共享同一块堆内存,当它们析构时会重复释放这块内存,触发未定义行为(程序崩溃、内存损坏等)。

另外你疑惑的“结构体变量地址大小为8但结构体本身大小为48”:&ValuesOut是指向Test1的指针,sizeof(&ValuesOut)是指针的大小,和结构体本身的大小无关——64位系统指针都是8字节,32位是4字节,不管它指向的对象多大。

二、解决方案

1. 最安全便捷的方式:用结构体赋值

直接用ValuesOut = Values;替换memcpy操作。C++的结构体赋值会自动调用成员的拷贝构造函数,对于std::string来说就是深拷贝,既安全又和memcpy一样便捷,完全不需要手动处理每个字段。

修改后的关键代码:

// 替换原来的memcpy行
ValuesOut = Values;

2. 如果必须用类似memcpy的批量拷贝(不推荐)

只有当结构体是POD类型时,memcpy才是合法安全的。你有两种选择:

  • 把std::string换成固定大小的char数组,比如char Text[64];,这样结构体变成POD类型,memcpy可以正常使用,但字符串长度会受限制。
  • 使用std::copy替代memcpy,但本质上和结构体赋值逻辑一致,代码反而更繁琐。

总结

不要用memcpy拷贝含非POD类型(比如std::string、std::vector等)的结构体,直接用赋值操作是最省心且安全的方案,完全满足你“便捷操作多字段结构体”的需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 03:35:18