Lifetime of a Span

What happens if I create a std::span from a vector, and then the vector goes out of scope? Is it safe to continue using the span?

No, it is not safe to use a std::span after the data it spans has gone out of scope. A std::span does not own the data it points to, so if the original data is destroyed, the std::span will be left pointing to invalid memory.

Consider this example:

#include <span>
#include <vector>
#include <iostream>

std::span<int> CreateSpan() {
  std::vector<int> vec{1, 2, 3, 4, 5};
  return std::span<int>{vec};  
}

int main() {
  std::span<int> span = CreateSpan();
  // vec no longer exists here
  for (int i : span) {      
    std::cout << i << "\n";  
  }
}
-572662307
-572662307
-572662307
-572662307
-572662307

In this code, the std::vector vec is created inside the CreateSpan function. A std::span is created from vec and returned from the function. However, vec is destroyed when CreateSpan ends, because it's a local variable.

In main, when we try to use span, we're accessing memory that has already been freed. This is undefined behavior and can lead to crashes or subtle bugs.

To avoid this, ensure that the std::span does not outlive the data it spans. One way to do this is to pass the data and the span around together:

#include <span>
#include <vector>

void ProcessData(
  std::vector<int> vec, std::span<int> span) {
  // Use vec and span here
}

int main() {
  std::vector<int> vec{1, 2, 3, 4, 5};
  ProcessData(vec, std::span<int>{vec});
}

Here, vec and span are passed to ProcessData together, and vec outlives span, so it's safe to use span inside ProcessData.

Another way is to ensure that the data outlives the span by allocating it on the heap:

#include <span>
#include <vector>
#include <memory>

int main() {
  auto vec = std::make_unique<
    std::vector<int>>(1, 2, 3, 4, 5);
  std::span<int> span{*vec};
  // Use span here
}

In this case, vec is allocated on the heap and it will live until the end of main, so it's safe to use span throughout main.

Array Spans and std::span

A detailed guide to creating a "view" of an array using std::span, and why we would want to

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Span vs Vector in C++
When should I use std::span over std::vector in C++? What are the key differences and trade-offs between these two types?
Creating a Span from a Vector
How can I create a std::span from a std::vector in C++? Can you provide an example?
Span Size and Stack Overflow
Is there a limit to the size of a std::span? Could creating a very large std::span lead to a stack overflow?
Modifying Elements Through a Span
If I modify an element through a std::span, does it affect the original data? Can you show an example?
Using Span as a Function Parameter
What are the benefits of using std::span as a function parameter instead of a reference to a container like std::vector or std::array?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant