简体   繁体   中英

C++17 unique_ptr lambda capture by value is ok, but not by reference

I have make a program showing that passing by value is fine but passing by reference will trigger SEGMENT FAULT.

Currently, there are two unique_ptr maker functions as new_unique_ptr and new_unique_ptr2 as follows

#include <functional>
#include <memory>

using namespace std;

template <class T, class Deleter>
unique_ptr<T, function<void(T *)>> new_unique_ptr(T *ptr, Deleter d) {
  return unique_ptr<T, function<void(T *)>>(ptr, [&](auto v) {
    if (v) {
      d(v);
    }
  });
}

template <class T, class Deleter>
unique_ptr<T, function<void(T *)>> new_unique_ptr2(T *ptr, Deleter d) {
  return unique_ptr<T, function<void(T *)>>(ptr, [=](auto v) {
    if (v) {
      d(v);
    }
  });
}

void free_int(int *v) { delete v; }

int main() {
  printf("0: %p\n", free_int);

  {
    printf("\n--- demo1 ---\n");

    auto v2 = new_unique_ptr2(new int(2), free_int);
    printf("value is %d\n", *v2);
  }

  {
    printf("\n--- demo2 ---\n");
    auto v = new_unique_ptr(new int(1), free_int);

    printf("value is %d\n", *v);
  }

  return 0;
}

Compile and run

g++ main.cc

./a.out

will show sample output as

0: 0x7f99c7efe209

--- demo1 ---
11: 0x7f99c7efe209
value is 2
22: 0x7f99c7efe209

--- demo2 ---
1: 0x7f99c7efe209
value is 1
2: 0x7fff3e5ae7e0
Segmentation fault (core dumped)

which indicates the passed by reference demo ( demo2 ) failed.

Really appreciate if someone could help explaining why~

In new_unique_ptr the lambda is capturing the function parameter d by-reference; d will be destroyed when new_unique_ptr returns, left the captured reference dangled. After that when the std::unique_ptr gets destroyed, the deleter is called on the dangling reference which leads to UB.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM