局部变量的引用传递的风险

众所周知,函数内的局部变量的声明周期在函数return后结束,所以如果将局部变量的引用传递给某个线程去执行就有可能导致断言。

也就是将局部变量的引用传递给线程使用是有风险的!

看如下代码

vois MyObject::funciton1()
{
    QString path = "filename.txt";
    m_workerThread->SetCallFuntion([&]()->QString {
			return WriteBigData(path.toStdString());
		});
	m_workerThread->start();
}

这里创建了一个线程去执行阻塞操作,该操作封装在一个lambda函数内,lambda函数的捕捉列表是当前父作用域的所有变量的引用。

也就是当线程执行WriteBigData(path.toStdString()), path变量可能已经由于funciton1()函数的退出而销毁了,所以如果执行path.toStdString()就会导致断言



为了验证这个原因导致的问题,我们可以打印一些调试信息来验证

vois MyObject::funciton1()
{
    QString path = "filename.txt";
    m_workerThread->SetCallFuntion([&]()->QString {
			std::cout << "线程开始执行\n";
			return WriteBigData(path.toStdString());
		});
	m_workerThread->start();
    std::cout << "当前函数已退出\n";
}

打印输出如下

验证成立,修改代码如下后问题解决

  QString path -> static QString path
posted @ 2024-04-12 15:26  HL棣  阅读(11)  评论(0编辑  收藏  举报