C++线程传参的几个误区

#include <iostream>
#include<thread>

using namespace std;

void ThreadFun(const int &arr1,char *pBuf)
{
    cout << arr1 << endl;
    cout << pBuf << endl;
    return;
}

int main()
{
    int temp = 10;
    char arr[20] = "Hello Word";
    std::thread t1(ThreadFun, temp,arr);
    t1.detach();
    std::cout << "主线程运行
";
}

以上代码有2个误区,

误区1:大家会认为线程函数第一个参数是引用,线程用的是detach(),则会出现一种问题,就是当主线程退出时,temp变量释放掉了,子线程的第一个参数是引用,所以地址也被释放掉了,而线程函数里面还用到了这个参数,就会出现用了已经释放的地址的问题,这种想法是错的。

解释:线程函数第一个参数使用的是引用(&arr1),但是实际调试时,它与调用时传进来的实参(temp)的地址不同,则表示它线程函数第一个参数不是实际的引用,是假的引用,只是做了个值的拷贝,所以不会出现用了已经释放的地址的问题。

线程函数第二个参数是指针,调试时发现地址实参和形参的地址相同,则指传参是有问题的,会出现用了已经释放的地址的问题,不建议使用指针。

误区2:大家会认为第二个参数不让使用指针,但是我也传字符串那我可以这样写,

#include <iostream>
#include<thread>

using namespace std;

void ThreadFun(const int &arr1,string &pBuf)
{
    cout << arr1 << endl;
    cout << pBuf.c_str() << endl;
    return;
}

int main()
{
    int temp = 10;
    char arr[20] = "Hello Word";
    std::thread t1(ThreadFun, temp,arr);
    t1.join();
    std::cout << "主线程运行
";
}

以上的写法形参和实参的地址不同,看起来没啥问题,但是实际也是错误的,这样写会出现一个问题,就是从代码上看线程函数开始前arr实参是被隐式转换为了string,

但是程序不确定啥时去转换,调试时有这种可能,就是主线程都退出了,arr还没有被转换为string,此时,主线程退出,arry被释放掉了,现在要把现在就相当与把一块不确定的地址转换为string,这是不对的。正确的使用方法,就是在传参的时候把arr强制转换为临时的string类型传递给线程就不会出现上面的问题。例如: 

std::thread t1(ThreadFun, temp,string(arr));
111
原文地址:https://www.cnblogs.com/zwj-199306231519/p/13532405.html