std::move后指针地址为什么没变呢?

为什么通过std::move(str1)调用后,str2的指针地址还没变呢? 难道不是已经delete str2了吗?

另外请教下:文档说:Although note that -in the standard library- moving implies that the moved-from object is left in a valid but unspecified state. 那这里的"unspecified state"是什么含义呢? state有哪些呢?

    std::string str1("hello");
    std::string str2("");
    printf("pointer1:%p,%p\n", &str1,&str2);
    str2 = std::move(str1);
    cout << str1;
    printf("pointer2:%p,%p\n", &str1,&str2);

输出:

pointer1:0x7fff0c5532b0,0x7fff0c5532a8
pointer2:0x7fff0c5532b0,0x7fff0c5532a8

阅读 5.5k
3 个回答

你的代码有问题。修改如下:

#include <string>
#include <iostream>
using namespace std;
int main() {
  std::string str1("hellohellohellohellohellohello");
  std::string str2("");
  printf("pointer1:%p,%p\n", str1.data(), str2.data());
  str2 = std::move(str1);
  cout << str1 << endl;
  printf("pointer2:%p,%p\n", str1.data(), str2.data());
  return 0;
}

你的代码的问题:

  1. 你测试用的字符串太短,因为有std::string针对短字符串做了优化,这种情况下你用move和不用move是没差别的。
  2. 你应该查看str1.data()str2.data(),而不是查看&str1&str2.

你会发现字符串足够长的话,指向str2的字符串资源就是原来str1的字符串,也就是说没有发生字符串拷贝。

简要的解释就是这个 state 是由实现决定的,标准只要求 valid


C++11 标准文档对 valid but unspecified state 术语的定义,在 n3337 17.3.26 401 。

an object state that is not specified except that the object’s invariants are met and operations on the object behave as specified for its type
[Example: If an object x of type std::vector<int> is in a valid but unspecified state, x.empty() can be
called unconditionally, and x.front() can be called only if x.empty() returns false. — end example ]

一个关于 move-safety 介绍的博客文章

你两个栈上变量,地址变个啥?

而且你对move的概念理解就有问题。人家“移动”的是对象里面的被包装内容,又不是对象本身的内存足迹。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题