不会溢出,前提是正确实现 generator 的 promise_type 和资源管理逻辑;协程状态须存于 promise_type 成员而非栈变量,析构时必须调用 handle.destroy(),消费侧需避免全量收集无限序列。

不会溢出,前提是正确实现 generator 的 promise_type 和资源管理逻辑。 协程本身不自动累积数据,co_yield 只是挂起并传出当前值,状态只保存必要变量(如 current、next),内存占用恒定 O(1)。溢出通常来自错误实现或调用侧滥用。
generator 中斐波那契状态必须用值语义或栈变量维护
协程的局部变量在挂起后仍需有效,但不能依赖函数栈上的临时对象。常见错误是把计算中间态存在栈上再 co_yield 引用:
- ❌ 错误:在
fibonacci()函数体内声明int a = 0, b = 1;,然后co_yield a;—— 这些变量生命周期仅限于协程函数帧,挂起后不可访问 - ✅ 正确:所有状态必须存入
promise_type成员(如int current;、int next;),由协程堆分配的 promise 对象长期持有 - ⚠️ 注意:
yield_value不负责存储,它只是接收传入值;真正存储逻辑必须写在promise_type::yield_value里,比如current_value = value;
协程 handle 必须被正确销毁,否则内存泄漏
每个协程实例背后是一个堆分配的 promise_type 对象,由 std::coroutine_handle 管理。如果 generator 对象被销毁但没调用 handle.destroy(),就会泄漏。
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
- generator 类析构函数中必须检查
handle是否非空,并调用handle.destroy() - 不要手动调用
handle.resume()后忘记判断handle.done(),否则重复 resume 或对已结束 handle 操作会 UB - 推荐用 RAII 封装:generator 构造时获取 handle,析构时自动 destroy;避免裸 handle 传递
无限序列本身不导致内存增长,但消费侧可能误建容器
generator 是惰性求值的,每次迭代只产生一个数。溢出往往发生在使用者身上:
- ❌ 错误:写
std::vector<int> v(gen.begin(), gen.end());</int>—— 试图把无限序列全塞进 vector,立刻 OOM - ✅ 正确:配合
std::views::take(N)或手写循环 + 计数控制,例如for (int i = 0; i - ⚠️ 注意:C++20 range adaptor 如
views::take本身不拷贝数据,只是包装迭代器逻辑,不会触发无限展开
最易被忽略的是 promise_type 析构时机与异常安全——如果 unhandled_exception 没处理,协程中途崩溃,handle 可能无法到达 destroy 调用点。务必在 promise_type::~promise_type() 里补一层防御性检查,或确保 generator 类的析构是 noexcept 且强异常安全。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!










