为什么 async() 写入临时变量而没有发生崩溃

why async() write on temporary variable and no crash happend

这是我编写的一些代码,用于测试临时变量上的 async()。 函数测试使用 async() 执行函数 write_A(A* a),并使用 future.wait_for() 等待一段时间的结果。如果超时,测试returns,A a2 会同时被释放,因为它是在栈上分配的。 write_A 写入 A* a 会崩溃。但实际上该程序运行良好。为什么异步执行的函数 write_A 可以写入已释放的堆栈临时变量?

struct A {
  string name;
  string address;
};

int write_A(A* a) {
  sleep(3);
  a->name = "tractor";
  a->address = "unknow";
  cout <<"write_A return" << endl;
  return 0;
}

void test(A* a) {
   A a2;
  future<int> fut = async(launch::async, write_A, &a2);
  auto status = fut.wait_for(chrono::milliseconds(1000));
  if (status == future_status::ready) {
    int ret = fut.get();
    *a = a2;
    cout <<"succ"<<endl;
  } else {
    cout <<"timeout"<<endl;
  }
}

void test2() {
  A a;
  test(&a);
}

int main ()
{
  test2();
  sleep(5);
  return 0;
}

我预计程序会崩溃,因为 write_A 写在测试 return 时已释放的对象指针上。但是程序输出:

超时

write_A return

这个对象

    future<int> fut

test 函数结束时被销毁。当调用 future destructor 时,它会阻塞直到共享状态准备就绪——这意味着 write_A 结束。因此,指向 test 函数内的 a 的指针始终有效。

本地对象的销毁顺序与其创建顺序相反,因此在本例中

A a2;
future<int> fut = async(launch::async, write_A, &a2);

因为第一个 fut 被删除,它的析构函数一直等到 write_A 完成。然后a2被销毁。