使用memcpy复制含non-POD类型结构体触发double free该如何解决
错误根因
你遇到的double free问题本质是memcpy不适合拷贝包含non-POD类型的结构体:
- 你的
config结构体中的Vector<int>是non-POD类型,内部持有指向堆内存的指针,自带构造、析构、拷贝逻辑。 memcpy是按字节逐位复制内存,会直接把原对象confrcvd里vector的内部指针原封不动复制到新对象config_ptr的vector成员中,导致两个vector对象持有同一块堆内存的地址。- 函数参数
confrcvd在函数执行结束出作用域时,会自动调用自身vector成员的析构函数释放堆内存;后续你delete config_ptr时,新对象的vector成员会再次尝试释放同一块内存,最终触发double free。
最优拷贝方案
对于包含non-POD成员的结构体,直接使用类型自带的拷贝构造/拷贝赋值逻辑即可,不要手动调用memcpy:
- 你当前的场景不需要自定义拷贝逻辑,编译器自动生成的默认拷贝构造函数就能满足需求:它会递归调用每个成员的拷贝构造函数,vector的拷贝构造会自行申请新的堆内存、复制所有元素,不会和原对象共享内存地址,完全规避double free问题。
- 如果你的结构体有特殊的拷贝规则,再自行实现拷贝构造函数和拷贝赋值运算符,遵守C++的三五法则即可。
- 额外优化建议:优先使用值语义而非裸指针管理内存,直接存储
Vector<config>而非Vector<config*>,可以省略手动new/delete的操作,进一步降低内存错误概率。
修正后的核心代码示例
struct config { Vector<int> list; Vector<int> listmode; int id; }; void config_req(struct config confrcvd) { // 直接调用拷贝构造函数生成新对象,替换原来的new+memcpy逻辑 struct config *config_ptr = new config(confrcvd); Vector<struct config *> configvector; configvector.push_back(config_ptr); // 对vector执行若干操作后删除元素 for(auto conf : configvector) { delete conf; } configvector.clear(); }
内容的提问来源于stack exchange,提问作者Raghavendra
相关产品推荐
相关产品推荐

