c++中包含string成员的结构体拷贝导致的double free问题

简介: c++中包含string成员的结构体拷贝导致的double free问题

最近调试代码遇到一个的问题,提示double free,但是找了好久也没有找到释放两次的地方,后来调试发现,是由于使用了一个包含string成员的结构体,这个结构体使用memcpy拷贝导致的问题;

 

代码如下:

 
#include <stdio.h>
#include <map>
#include <string>
#include <stdlib.h>
#include <memory>
#include <iostream>
#include <string.h>
 
using namespace std;
 
typedef struct TestPtrInfo
{
    string name;
    int data;
}TestPtrInfoSt;
 
class testPtr
{
public:
    testPtr(int i,TestPtrInfoSt* info):m_id(i)
    {
        memcpy(&m_info, info, sizeof(TestPtrInfoSt));  //导致出问题的这一行
        cout<<m_id<<" name: "<<m_info.name<<" testPtr start..."<<endl;
    }
 
    ~testPtr()
    {
        cout<<m_id<<" name: "<<m_info.name<<" testPtr end..."<<endl;
    }
private:
    int m_id;
    TestPtrInfoSt m_info;
};
 
 
int main()
{
 
    //map<string, shared_ptr<testPtr> >testMap;
    map<string, testPtr* >testMap;
  
  TestPtrInfoSt info;
  for (int i = 0; i < 10 ; i++ )
  {
    info.name = "no-"+to_string(i);
    testMap[to_string(i)] = new testPtr(i, &info);    
  }
    
 
    auto iterPtr = testMap.find("1");
  delete iterPtr->second;
    testMap.erase(iterPtr);
    cout <<"1, reslease "<<endl;
 
  return 0;
}


这个不是正式代码,用测试代码复现的问题;

编译没问题,运行时会挂掉:


如上图,会报段错误,用gdb调试,打印堆栈信息如下:


从上面的堆栈信息中,看到这么一行:

#2  0xb7f4a985 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::~basic_string() ()
   from /usr/lib/i386-linux-gnu/libstdc++.so.6


这里是string类的析构函数,在这里想到可能是memcpy拷贝结构体导致的,修改后测试不会再出现问题。


关于包含类的结构体,一般不能使用memcpy拷贝,会出问题。


参见:


memcpy复制字符串的注意事项/memcpy不能用来拷贝类类型 - hchacha - 博客园

https://www.cnblogs.com/hchacha/p/7615631.html


目录
打赏
0
1
1
0
47
分享
相关文章
C++ String揭秘:写高效代码的关键
在C++编程中,字符串操作是不可避免的一部分。从简单的字符串拼接到复杂的文本处理,C++的string类为开发者提供了一种更高效、灵活且安全的方式来管理和操作字符串。本文将从基础操作入手,逐步揭开C++ string类的奥秘,帮助你深入理解其内部机制,并学会如何在实际开发中充分发挥其性能和优势。
模拟实现c++中的string
模拟实现c++中的string
【c++丨STL】string模拟实现(附源码)
本文详细介绍了如何模拟实现C++ STL中的`string`类,包括其构造函数、拷贝构造、赋值重载、析构函数等基本功能,以及字符串的插入、删除、查找、比较等操作。文章还展示了如何实现输入输出流操作符,使自定义的`string`类能够方便地与`cin`和`cout`配合使用。通过这些实现,读者不仅能加深对`string`类的理解,还能提升对C++编程技巧的掌握。
144 5
【c++丨STL】string类的使用
本文介绍了C++中`string`类的基本概念及其主要接口。`string`类在C++标准库中扮演着重要角色,它提供了比C语言中字符串处理函数更丰富、安全和便捷的功能。文章详细讲解了`string`类的构造函数、赋值运算符、容量管理接口、元素访问及遍历方法、字符串修改操作、字符串运算接口、常量成员和非成员函数等内容。通过实例演示了如何使用这些接口进行字符串的创建、修改、查找和比较等操作,帮助读者更好地理解和掌握`string`类的应用。
93 2
双重释放(Double Free)
【10月更文挑战第12天】
203 2
让星星月亮告诉你,通过反射创建类的实例对象,并通过Unsafe theUnsafe来修改实例对象的私有的String类型的成员属性的值
本文介绍了如何使用 Unsafe 类通过反射机制修改对象的私有属性值。主要包括: 1. 获取 Unsafe 的 theUnsafe 属性:通过反射获取 Unsafe类的私有静态属性theUnsafe,并放开其访问权限,以便后续操作 2. 利用反射创建 User 类的实例对象:通过反射创建User类的实例对象,并定义预期值 3. 利用反射获取实例对象的name属性并修改:通过反射获取 User类实例对象的私有属性name,使用 Unsafe`的compareAndSwapObject方法直接在内存地址上修改属性值 核心代码展示了详细的步骤和逻辑,确保了对私有属性的修改不受 JVM 访问权限的限制
84 4
|
4月前
|
【C++打怪之路Lv8】-- string类
【C++打怪之路Lv8】-- string类
46 1
|
4月前
|
深度剖析C++string(中)
深度剖析C++string(中)
75 0
深度剖析C++string(上篇)(2)
深度剖析C++string(上篇)(2)
57 0
|
4月前
|
深度剖析C++string(上篇)(1)
深度剖析C++string(上篇)(1)
43 0
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等