问题描述
示例代码
#include<stdlib.h>
#include<stdio.h>
#include<iostream>
#include<string>
int main(){
std::string str = "Hello World."; // 非 POD 数据类型
std::cout<< "Origin:\n";
std::cout<< "str value: "<<str << " address:" << &str << std::endl;
printf("c_str adress:%p\n", str.c_str());
std::string str_m = std::move(str); // 移动*********
std::cout<< "After move:\n";
std::cout<< "str value: "<<str << " address:" << &str << std::endl;
std::cout<< "str_m value: "<<str_m << " address:" << &str_m<< std::endl;
printf("c_str adress:%p\n", str.c_str());
printf("c_str_m adress:%p\n", str_m.c_str());
return 0;
}
运行结果
Origin:
str value: Hello World. address:0x7fff0addf670
c_str adress:0x7fff0addf680
After move:
str value: address:0x7fff0addf670
str_m value: Hello World. address:0x7fff0addf690
c_str adress:0x7fff0addf680
c_str_m adress:0x7fff0addf6a0
疑问
注意代码中的标*行,对于非 POD 数据结构 str::string,std::move() 会将该数据结构对象 str 中所包含的数据的所有权转交给 sr_m,期间并不发生内存的拷贝和移动。这段代码执行完后,我有两点疑问:
- 代码的运行结果显示, str 的地址在移动前后不变,而 str 的值已经为空。地址不变意味着 str 对应的内存区域是不变的,而 str 的值为空说明该内存区域已经不再储存 "Hello World." 了。所以,这块内存看起来应该是被改动了。
- 代码运行结果显示 str_m 的地址与 str 并不相同,但是 str_m 的值为 “Hello World.”, 也就是说,一个新的内存区域被写入了 "Hello World."。
综上, std::move() 的行为更像是将 str 的内容拷贝给 str_m,然后清空了 str 所对应内存的内容。并不是所谓的“不会拷贝”。所以,在这个例子中哪里出了问题,好苦恼
期待大家的解答。