You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

std::vector移动构造是否窃取资源?移动后原指针是否有效?

问题分析:vector移动构造后原指针的合法性

首先看代码片段:

void test(std::vector<int> && vec){
    auto const ptr = data(vec);
    auto new_vec {std::move(vec)};
    (void)*ptr; // UB or not?
};

核心结论

这是未定义行为(UB),MSVC-17.65下测试可行只是编译器特定实现带来的巧合,绝对不是合法用法。

原因解释

  1. C++标准对容器移动构造的规定
    容器被移动构造后,原容器会处于有效但未指定的状态:

    • “有效”仅表示可以安全调用不依赖内部状态的成员函数(比如析构函数、empty());
    • “未指定”意味着你不能假设原容器的内部存储、data()返回值等还保持移动前的状态。
  2. vector移动构造后的原容器状态
    对于std::vector,移动构造完成后,原vec的data()返回值是未定义的:

    • 有些编译器实现会把原vec的内部指针置为空,此时ptr就是野指针,解引用直接触发错误;
    • 像MSVC的当前版本,可能暂时保留原指针,但这块内存的所有权已经完全转移给new_vec——后续new_vec的任何操作(比如析构、扩容)都会让ptr变成无效指针,此时解引用属于非法访问他人所有的内存,完全符合未定义行为的定义。
  3. MSVC测试可行的本质
    这只是MSVC特定实现的巧合,不代表符合标准规范。换用GCC、Clang等其他编译器,或者升级/降级MSVC版本,都可能出现崩溃、数据损坏等异常情况。

正确用法

如果需要访问原vec的存储内容,应该从移动后的合法所有者new_vec获取指针:

void test(std::vector<int> && vec){
    auto new_vec {std::move(vec)};
    auto const ptr = data(new_vec);
    (void)*ptr; // 合法,ptr指向new_vec的有效内部存储
};

内容的提问来源于stack exchange,提问作者Red.Wave

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 18:57:46