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

为何std::move后std::string对象打印地址不同?移动是否生效?

你混淆了对象地址和内部缓冲区地址
  • 你打印的&str和&s2是std::string对象自身在栈上的内存地址,这两个是完全独立的对象实例,栈地址肯定不一样,和移动操作本身没有关系。
  • 移动操作的核心是转移对象内部管理的资源(比如存储字符串的堆内存缓冲区),不是让两个对象共用同一个栈地址。
  • 要验证移动是否发生,应该打印它们内部缓冲区的地址,而非对象本身的地址。可以用data()方法获取内部字符数组的指针。

修改后的验证代码:

#include <iostream>
#include <string>

void test1(std::string&& str) {
    // 打印str内部缓冲区地址
    std::cout << "str内部缓冲区地址: " << static_cast<void*>(str.data()) << std::endl;
    std::string s2 = std::move(str);
    // 打印s2内部缓冲区地址
    std::cout << "s2内部缓冲区地址: " << static_cast<void*>(s2.data()) << std::endl;
    // 打印移动后str的内部缓冲区地址(通常会变为空指针)
    std::cout << "移动后str内部缓冲区地址: " << static_cast<void*>(str.data()) << std::endl;
    
    // 对比对象本身的地址(本来就不同)
    std::cout << "str对象地址: " << &str << std::endl;
    std::cout << "s2对象地址: " << &s2 << std::endl;
}

int main () {
    test1("abc");
}

运行后你会看到:
s2的内部缓冲区地址和移动前str的地址完全一致,说明资源确实被转移了;而移动后的str内部地址通常会变成nullptr(不同标准库实现可能有差异,但原对象不再持有原来的资源)。

另外补充:std::move本身只是一个类型转换工具,把左值转成右值引用,它不会直接移动资源,真正的资源转移是在调用std::string的移动构造函数时完成的。

内容的提问来源于stack exchange,提问作者Sensiblewings47

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 07:03:14