zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    MySQL Binlog信息查看
    MySQL Binlog和Relaylog生成和清理
    MySQL Binlogbinlog_format参数
    Maven的核心概念及安装
    Maven工程约定目录结构
    解决 internal/modules/cjs/loader.js:983 throw err; ^ Error: Cannot find module ‘express‘ 报错问题
    Linux之开机、重启和用户登录注销等操作
    Linux之系统文件概述
    Linux之基本指令
    express的基本使用
  • 原文地址:https://www.cnblogs.com/fensnote/p/13436489.html
Copyright © 2011-2022 走看看