移动std::vector<T>后,原std::span<T>是否仍有效且指向新vector?
std::vector移动后,原std::span是否仍有效?
结论:此时span s仍然有效,不存在未定义行为风险
核心逻辑拆解:
vector移动的标准语义
C++标准明确规定,vector的移动构造/赋值操作不会释放原内存,只是把内部管理内存的指针、容量、大小等成员从原对象(v)转移到新对象(x)。移动完成后,原vector v处于「有效但未指定状态」,但x会完全接管原内存缓冲区,且该缓冲区的物理地址不会改变。span的本质是内存视图
span是对连续内存的非拥有式引用,它只保存两个核心信息:内存起始地址、元素数量。当初始化s = std::span<T>(v.begin(), 10)时,s记录的是v当时内存缓冲区的起始地址,以及前10个元素的范围。移动后span的有效性
因为vector移动只是转移内存所有权,原内存地址不变,且新vector x会维护这块内存的有效性(直到x被销毁或触发扩容),所以span s指向的内存仍然是合法、可访问的,完全符合标准要求,不属于未定义行为。
需要注意的例外情况
如果后续对x执行了会触发内存重新分配的操作(比如push_back元素导致容量不足),x会申请新的内存并拷贝/移动元素,原内存会被释放,此时span s就会失效,访问它会导致未定义行为。
内容的提问来源于stack exchange,提问作者bradgonesurfing
相关产品推荐
相关产品推荐

