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
.
Answers to questions are automatically generated and may not have been reviewed.
std::span
A detailed guide to creating a "view" of an array using std::span
, and why we would want to