0

This is some code I write to test async() wirte on tempory variables. the function test use async() the execute a function write_A(A* a), and use future.wait_for() to wait the result for a period of time. If it'is timeout, test returns, the A a2 will be freeed at the same time, because it is allocated on stack. The write_A write on A* a would crash. But in fact the program works fine. Why the async executed function write_A can write on freed stack tempory variable?

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;
}

I expect the program will crash because write_A write on a pointer of object which has beed released when the test returned. But the program output:

timeout

write_A return

Joey
  • 175
  • 7

1 Answers1

1

This object

    future<int> fut

is destroyed at the end of test function. When future destructor is called, it blocks until shared state is ready - it means write_A is ended. So, pointer to a inside test function is valid all time.

Local objects are destroyed in reverse order of their creations, so in this case

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

as first fut is deleted, its destructor waits until write_A is completed. Then a2 is destroyed.

rafix07
  • 20,001
  • 3
  • 20
  • 33
  • Maybe add that it does that only when returned from `std::async` – Mike van Dyke Jul 22 '19 at 10:59
  • @rafix07 Thanks for your reply. I print the timestamp and some message and find the function `test` is blocked when the `fut` released as you said. If I want the `test` returned immediately when timeout happend, is there some ways to approach that? Thanks a lot. – Joey Jul 23 '19 at 01:53
  • @Joey You may read [this](https://stackoverflow.com/questions/12086622/is-there-a-way-to-cancel-detach-a-future-in-c11). Short answer is No, you cannot interrupt the execution of async's task. – rafix07 Jul 23 '19 at 03:51