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

使用std::move移动std::list元素后得到无效输出的问题求解

问题原因分析

你代码的核心问题出在移动操作的实现逻辑有误,具体有两处错误:

  • 没有实际触发移动构造:std::move()本身仅负责将左值转换为右值引用类型,不会主动执行移动逻辑。你用Data&& d1右值引用接收返回值,本质是给std::list中存储的原元素起了个别名,没有生成新的Data对象,元素内容依然存放在list的内存空间中。
  • 产生悬垂引用:后续调用pop_front()时,list会直接销毁队首的原元素,此时d1引用指向的是已经被回收的内存,后续访问d1.topic、d1.msg属于未定义行为,自然无法得到预期输出。
修复方案

仅需要修改移动逻辑的接收类型,改为值接收即可真正触发移动构造:

#include <iostream>
#include <string>
#include <list>

struct Data {
    std::string topic {};
    std::string msg {};

    Data(const std::string& topic, const std::string& msg) {
        this->topic = topic;
        this->msg = msg;
    }
};

int main() {
    std::list<Data> data_list;
    data_list.push_back(Data("A", std::string(1000, 'a')));
    data_list.push_back(Data("B", std::string(1000, 'b')));
    data_list.push_back(Data("C", std::string(1000, 'c')));
    data_list.push_back(Data("D", std::string(1000, 'd')));
    data_list.push_back(Data("E", std::string(1000, 'e')));
    
    while (!data_list.empty()) {
        std::cout << (void*)&data_list.front() << "\n";
        // 改为值接收,触发Data的移动构造
        Data d1 = std::move(data_list.front());
        data_list.pop_front();
        std::cout << d1.topic << ", " << d1.msg << "\n";
        std::cout << (void*)&d1 << "\n\n";
    }
    std::cout << std::endl;
}
逻辑说明
  • 改为Data d1 = std::move(data_list.front());后,会调用Data类隐式生成的移动构造函数,将原list元素中两个std::string的内部数据指针直接转移到局部变量d1中,没有大块内存拷贝,符合移动操作的性能预期。
  • 后续执行pop_front()销毁的是已经被移动后的空壳对象,不会影响d1的正常访问。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 04:57:00