捕获成员函数指针为引用导致段错误的原因分析
为什么这段C++代码会引发段错误?
你的问题核心在于lambda对局部变量的引用捕获导致悬空引用,具体分析如下:
问题根源:悬空的成员函数指针引用
在init函数中,member_fn是函数的形参,属于栈上的局部变量。你写的lambda用&member_fn按引用捕获了这个变量。当init函数执行完毕返回时,它的栈帧会被销毁,member_fn占用的内存会被释放或重新分配。此时返回的std::function里的lambda持有的就是一个悬空引用——指向已经不存在的内存地址。
当你在main里调用func()时,lambda尝试通过这个悬空引用访问成员函数指针,这属于C++中的未定义行为,直接表现为段错误。按值捕获为什么能正常工作?
如果你把捕获改成按值(去掉&,写成[&foo, member_fn]),lambda会在内部复制一份member_fn的副本。这个副本存储在lambda对象自身的内存中,和init的栈帧无关。即使init函数执行完毕,lambda的副本依然有效,调用(foo.*member_fn)()时使用的是这个有效的副本,自然能正常执行。补充:关于
foo的捕获
你代码里foo是按引用捕获的,但这里不会出问题——因为foo是main函数中的局部变量,在调用func()时它的生命周期还没结束,引用是有效的。真正导致段错误的只有member_fn的悬空引用。
内容的提问来源于stack exchange,提问作者Jason Fernandez
相关产品推荐
相关产品推荐

