Reputation: 101
It's common knowledge that returning a pointer to a stack variable is generally a bad idea:
int* foo() {
int i = 0;
return &i;
}
int main() {
int* p = foo();
}
In the example above, my understanding is that the int
is destroyed and so p
is a dangling pointer.
I am wondering about the extent to which this applies to the newly introduced coroutines of C++20:
generator<span<byte>> read(stream& s) {
array<byte, 4096> b;
while (s.is_open()) {
const size_t n = s.read_some(b);
co_yield span(b, n);
}
}
int main() {
stream s;
for (span<byte> v : read(s)) {
/* ... */
}
}
In this example, the coroutine read
yields a span
view into the local buffer b
. Internally, that view stores a pointer to the buffer. Will that pointer ever be dangling when v
is used with the body of the range-for
loop?
For context, the coroutine code in the second example is modeled after the code in my own project. There, AddressSanitizer ends the program with a "use-after-free" error. Ordinarily I'd consider that enough to answer my question, but since coroutine development is still coming along at this point in time (my project is using boost::asio::experimental::coro
, emphasis on "experimental"), I was wondering if the error was caused by a bug with generator
's implementation or if returning pointers in this way is fundamentally incorrect (similar to the first example).
Upvotes: 10
Views: 327
Reputation: 40013
With language coroutines, this has to be safe: the lifetime of b
must continue until the generator is finished, so pointers to it must be useful that long.
Upvotes: 2