Torch_HXM 2023-10-26 22:53 采纳率: 50%
浏览 4

关于移动语义的内存表现

问题描述

示例代码

#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 所对应内存的内容。并不是所谓的“不会拷贝”。所以,在这个例子中哪里出了问题,好苦恼

期待大家的解答。

  • 写回答

2条回答 默认 最新

  • CSDN-Ada助手 CSDN-AI 官方账号 2023-10-27 09:05
    关注

    【以下回答由 GPT 生成】

    问题解答:

    你对于 std::move() 的行为的理解是正确的。std::move() 并不会直接转移对象在内存中的位置,而是转移了对象的资源所有权。

    在你的代码中,对于 std::string str = "Hello World."; 这行代码,编译器会创建一个临时对象(拷贝构造)。然后,通过 std::move() 将该临时对象的资源所有权转移到 str_m 中。这个资源所有权包括指向字符串数据的指针以及字符串的长度等信息。

    因此,当你在移动后的 str 中访问数据时,你实际上会得到无效的结果,因为资源已经被转移给了 str_m。但是,这并不表示 str 对应的内存区域没有变化。只是这个区域的数据已经无效化了,可以认为它是“空”的。

    对于移动构造函数,它会减少不必要的拷贝操作和资源的分配/释放,提高了性能。但并不意味着它会改变对象在内存中的位置。移动构造函数只能移动对象的资源,不能移动对象本身在内存中的位置。

    如果你想要验证移动构造函数的行为,可以考虑使用自定义类,在类的移动构造函数中打印相关信息,以便进行跟踪和调试。

    希望以上解答能够帮助你理解移动语义和内存表现。如果还有其他问题,请随时向我提问。


    如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^
    评论

报告相同问题?

问题事件

  • 创建了问题 10月26日

悬赏问题

  • ¥30 关于用python写支付宝扫码付异步通知收不到的问题
  • ¥50 vue组件中无法正确接收并处理axios请求
  • ¥15 隐藏系统界面pdf的打印、下载按钮
  • ¥15 MATLAB联合adams仿真卡死如何解决(代码模型无问题)
  • ¥15 基于pso参数优化的LightGBM分类模型
  • ¥15 安装Paddleocr时报错无法解决
  • ¥15 python中transformers可以正常下载,但是没有办法使用pipeline
  • ¥50 分布式追踪trace异常问题
  • ¥15 人在外地出差,速帮一点点
  • ¥15 如何使用canvas在图片上进行如下的标注,以下代码不起作用,如何修改