std::函数捕获中的悬空引用。为什么是未定义的行为? 我有两个C++程序,它们都使用函数捕获。其中一个成功,退出代码0,但另一个导致分段错误错误。std::shared_ptr()是通过引用捕获的,应该在调用lambda之前销毁。如果是这样的话,那么为什么我的第一个项目以成功告终,而第二个项目却没有成功 成功计划 #包括 #包括 #包括 #包括 std::函数lambda; void赋值_闭包(){ std::shared_ptr ptr=std::make_shared(“nope”); lambda=[&ptr](){ std::cout

std::函数捕获中的悬空引用。为什么是未定义的行为? 我有两个C++程序,它们都使用函数捕获。其中一个成功,退出代码0,但另一个导致分段错误错误。std::shared_ptr()是通过引用捕获的,应该在调用lambda之前销毁。如果是这样的话,那么为什么我的第一个项目以成功告终,而第二个项目却没有成功 成功计划 #包括 #包括 #包括 #包括 std::函数lambda; void赋值_闭包(){ std::shared_ptr ptr=std::make_shared(“nope”); lambda=[&ptr](){ std::cout,c++,reference,functional-programming,shared-ptr,capture,C++,Reference,Functional Programming,Shared Ptr,Capture,未定义的行为并不意味着segfault,它意味着任何东西。“它可以工作”或“格式化硬盘驱动器”或“segfault”或“通过电子邮件将浏览器历史记录和密码发送给所有联系人” 在本例中,堆栈和堆的垃圾内存恰巧与非垃圾内存一样排列 为了防止这种情况,除非lambda和所有副本在当前作用域结束之前被丢弃,否则不要使用任何类型的[&]捕获 < >无法确定C++上所有悬空引用。以不产生99%代码的悬空引用风险的方式编写代码。在1%中,无论出于何种原因,都要非常小心、批注,并包含没有悬空引用的证明。 有许多

未定义的行为并不意味着segfault,它意味着任何东西。“它可以工作”或“格式化硬盘驱动器”或“segfault”或“通过电子邮件将浏览器历史记录和密码发送给所有联系人”

在本例中,堆栈和堆的垃圾内存恰巧与非垃圾内存一样排列

为了防止这种情况,除非lambda和所有副本在当前作用域结束之前被丢弃,否则不要使用任何类型的
[&]
捕获

< >无法确定C++上所有悬空引用。以不产生99%代码的悬空引用风险的方式编写代码。在1%中,无论出于何种原因,都要非常小心、批注,并包含没有悬空引用的证明。 有许多工具可以或多或少地帮助追踪悬而未决的引用,但没有一个工具足够可靠,足以对付坚持做蠢事的程序员。要求工具推荐显然是离题的。

成功的程序也是如此
#include <string>
#include <memory>
#include <iostream>
#include <functional>

std::function<void()> lambda;

void assign_closure() {
  std::shared_ptr<std::string> ptr = std::make_shared<std::string>("nope");
  lambda = [&ptr]() {
    std::cout << "Trying to print this should segault: " << *ptr << std::endl;
  };
}

int main(int, char*[]) {
  assign_closure();
  lambda();
  return 0;
}
#include <string>
#include <memory>
#include <iostream>
#include <functional>

std::function<void()> lambda;

void assign_closure() {
  std::shared_ptr<std::string> ptr = std::make_shared<std::string>("nope");
  lambda = [&ptr]() {
    std::cout << "Trying to print this should segault: " << *ptr << std::endl;
  };
}

void do_some_work() {
  std::cout << "doing some work" << std::endl;
}

int main(int, char*[]) {
  assign_closure();
  do_some_work();
  lambda();
  return 0;
}