C++ Lambda Capture Error | 'dangling reference' Crash and Capture Mistakes Solution

C++ Lambda Capture Error | 'dangling reference' Crash and Capture Mistakes Solution

이 글의 핵심

C++ lambda capture error C++, "dangling, reference", Introduction: "Lambda stored but crashes" explained in detail with practical examples.

Introduction: “Lambda Stored but Crashes"

"Reference-captured variable already destroyed”

C++11’s lambda allows writing anonymous functions concisely, but incorrect capture (how lambda uses external variables) causes dangling references or unexpected behavior.

Below is an implementation example using C++. Understand the role of each part while examining the code.

// ❌ Dangling reference
std::function<int()> createLambda() {
    int x = 42;
    return [&x]() { return x; };  // Capture x by reference
}  // x destroyed

int main() {
    auto lambda = createLambda();
    std::cout << lambda() << '\n';  // ❌ Accessing destroyed variable → crash
}

What This Guide Covers:

  • Value capture vs reference capture
  • Preventing dangling references
  • this capture
  • Init capture (C++14)
  • 10 common lambda errors

1. Lambda Capture Basics

Capture Methods

Here is detailed implementation code using C++. Understand the role of each part while examining the code.

int x = 10;
int y = 20;

// [=]: Capture all variables by value
auto lambda1 = [=]() { return x + y; };

// [&]: Capture all variables by reference
auto lambda2 = [&]() { x = 30; return x + y; };

// [x]: Capture only x by value
auto lambda3 = [x]() { return x * 2; };

// [&x]: Capture only x by reference
auto lambda4 = [&x]() { x = 30; };

// [x, &y]: x by value, y by reference
auto lambda5 = [x, &y]() { return x + y; };

// [=, &y]: Default value, only y by reference
auto lambda6 = [=, &y]() { y = 30; return x + y; };

mutable Lambda

Here is detailed implementation code using C++. Understand the role of each part while examining the code.

int x = 10;

// ❌ Value capture cannot modify
auto lambda1 = [x]() {
    // x = 20;  // Compile error: cannot assign to a variable captured by copy
};

// ✅ Can modify with mutable
auto lambda2 = [x]() mutable {
    x = 20;  // OK (modifies internal copy)
    return x;
};

std::cout << lambda2() << '\n';  // 20
std::cout << x << '\n';  // 10 (original unchanged)

2. Value Capture vs Reference Capture

Value Capture [=]

Below is an implementation example using C++. Try running the code directly to check its operation.

int x = 10;

auto lambda = [=]() {  // Copy x
    return x * 2;
};

x = 20;  // Change original
std::cout << lambda() << '\n';  // 20 (value at capture time: 10)

Characteristics:

  • Copies value at capture time
  • No effect from original changes
  • Safe (no dangling references)

Reference Capture [&]

Below is an implementation example using C++. Try running the code directly to check its operation.

int x = 10;

auto lambda = [&]() {  // Reference x
    return x * 2;
};

x = 20;  // Change original
std::cout << lambda() << '\n';  // 40 (current value: 20)

Characteristics:

  • References original
  • Original changes immediately reflected
  • Dangerous (dangling if original destroyed)

Summary

Key Points

  1. Value capture [=]: Safe, copies value
  2. Reference capture [&]: Dangerous, can dangle
  3. mutable: Allows modifying captured values
  4. [this]: Captures this pointer
  5. [*this]: Copies entire object (C++17)

When to Use

Use value capture when:

  • Lambda outlives captured variables
  • Don’t need to modify original
  • Want safety

Use reference capture when:

  • Need to modify original
  • Large objects (performance)
  • Lambda lifetime is short

Don’t use:

  • Reference capture when lambda outlives variable
  • Capturing temporary objects

Best Practices

  • ✅ Default to value capture [=]
  • ✅ Use reference capture [&] carefully
  • ✅ Use shared_ptr for lifetime management
  • ❌ Don’t return lambda with reference capture
  • ❌ Don’t ignore dangling references

Master lambda capture for safer C++ code! 🚀