• c++线程中使用detach()导致的内存非法引用问题


    #include <iostream>
    #include"stdafx.h"
    #include<vector>
    #include<map>
    #include<string>
    #include<thread>
    
    
    
    
    using namespace std;
    class A
    {
    public:
        int m_i;
        //类型转换构造函数,可以把一个int整型转化成一个A类对象
        A(int a) :m_i(a) { cout << "[A::A(int a)构造函数执行]" << this << endl; }
        A(const A& a) :m_i(a.m_i) { cout << "[A::A(int a)拷贝构造函数执行]" << this << endl; }
        ~A() { cout << "[A::A(int a)析构函数执行]" << this << endl; }
    };
    
    //void myPrint(const int& i, char* pmybuf)//(解释1)i的地址与传入参数的地址不一样,这个引用是安全的,实际上是值传递
    //void myPrint(const int i, const string &pmybuf)
    //{
    //    cout << i << endl;
    //    //cout << pmybuf << endl;//pmybuf的地址与传入参数的地址相同,不安全,指针在detach中绝对会有问题
    //    cout << pmybuf.c_str() << endl;//转换为字符串变量经历了隐式类型转化,地址不同
    //}
    void myPrint(const int i, const A& pmybuf)
    {
        cout << &pmybuf << endl;//这里打印对象地址
        return;
    }
    int main()
    
    {
        //一、传递临时对象作为线程参数
        //(1.1)要避免的陷阱  传入的参数地址不同(解释1)
        {
        //int mvar = 1;
        //int& mvary = mvar;//两个变量地址相同
        //char mybuf[] = "this is a test";
        ///*thread mytob(myPrint, mvar, mybuf);*///(解释2)但是,在执行的时候mybuf到底是什么时候转换成string的
        //                                   //事实上存在mybuf都被回收了,main函数执行完了,系统才用mybuf转string的可能性。
        ////mytob.join();
        //thread mytob(myPrint, mvar,string (mybuf));//这里直接将mybuf转化成string对象,这是一个可以保证在线程中保持稳定的现象
        //mytob.detach();//子线程和主线程分别执行
        }
    
        //(1.2)要避免的陷阱  传入的参数地址不同(解释2)
        {
            int mvar = 1;
            int mysecondpar = 12;
            //thread mytob(myPrint, mvar, mysecondpar);//希望mysecondpar转成A类型对象传递给myPrint的第二个参数 两个参数地址相同
            thread mytob(myPrint, mvar, A(mysecondpar));//先强制转换后每次执行,必然先执行构造函数执行
            //mytob.join();
            mytob.detach();//如果子线程执行完,什么都没有打印,说明在执行线程之前mysecondpar已经被回收了,整型变量无效
                           //在创建线程的同时构造临时对象的方法传递参数是可行的
        }
        //cout << "I love China" << endl;
    //事实1:只要用临时构造的A类对象作为参数传递给线程,那么一定能够在主线程执行完毕前将线程函数的第二个参数构造出来,从而确保即使detach子线程也能安全运行
    
    
        return 0;
    
        //结论:
        //a)如果传递简单类型如int类型,建议直接值传递
        //b)在创建线程的同时构造临时对象的方法传递参数时可行的。要避免隐式类型转换。在创建线程这一行中构造出临时对象来,然后在函数参数中用引用来接,否则系统会多构造一次对象,浪费资源。
    }
  • 相关阅读:
    SpringBoot测试类异常java.lang.Exception: No tests found matching
    Tomcat启动时Creation of SecureRandom instance for session ID很慢
    CentOS7的docker下载后启动失败 Job for docker.service failed because the control process exited with
    Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'img_id'
    阿里云安装MySQL
    阿里云Centos8安装Docker
    如何通过JAVA代码上传图片和视频到阿里云服务器
    使用FDFS上传图片到服务器报错 ERROR server: 39.100.67.73:22122, response status 2 != 0
    生产者消费者模式
    JUC--Lock锁和Condition条件
  • 原文地址:https://www.cnblogs.com/ymj11/p/13860946.html
Copyright © 2020-2023  润新知