多线程共享栈上SharedVec对象时出现堆损坏问题
问题根源分析
你的堆损坏问题完全是线程参数传递错误导致的未定义行为,和对象在栈还是堆上无关——只是栈上的内存布局更容易触发非法访问的明显问题而已。
看你创建线程的代码:
std::thread t(check, std::bind(&sv));
这里犯了两个关键错误:
check函数需要的参数是SharedVec*类型,但你传递的是std::bind(&sv)返回的无参可调用对象(std::function<void()>),类型完全不匹配。- 编译器在这种情况下没有报错,是因为它尝试将
std::function对象的内存地址强制转换为SharedVec*,这直接导致线程里的check函数拿着一个完全无效的指针去操作sv->v——相当于在乱读乱写内存,堆损坏就是这么来的。
为什么堆上创建对象时你没看到问题?大概率是你堆上创建时,线程的写法改成了正确的形式:
SharedVec * sv = new SharedVec(); std::thread t(check, sv); // 直接传递指针,类型匹配
这种情况下参数传递正确,线程拿到的是有效的对象指针,自然不会有非法访问。
修正代码
把栈上创建对象时的线程创建代码改成正确的形式,去掉多余的 std::bind:
int main() { SharedVec sv; std::thread t(check, &sv); // 直接传sv的地址,类型匹配 while (true) { std::vector<int> tmp; m.lock(); tmp = sv.v; sv.v.clear(); m.unlock(); } t.join(); return 0; }
额外注意点
你的代码里两个 while(true) 都是死循环,t.join() 永远不会被执行到,虽然这不是堆损坏的直接原因,但实际开发中需要添加退出逻辑,避免程序无法正常结束。
内容的提问来源于stack exchange,提问作者Youli Luo
相关产品推荐
相关产品推荐

