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

无法在两个C++类间共享容器:问题复现与求助

问题:生产者消费者共享容器无数据交互

尝试在生产者类Foo1、消费者类Foo2之间通过std::shared_ptr共享容器,生产者向绑定key的队列推数据,消费者读取时始终无数据。无编译错误,但运行结果不符合预期。

可复现代码

main.cpp

#include "foo_1.h"
#include "foo_2.h"

#include <iostream>

Foo1 foo1;
Foo2 foo2;

int main(int argc, char* argv[])
{
    std::queue<shared_container> q;
    SharedContainer map = *g_map;
    // 1是本示例中预设的key,绑定空队列
    map[1] = q;


    // 向队列插入数据,预期队列大小=1
    foo1.producer();
    // 读取队列,预期大小=1,实际为0
    foo2.consumer();

    // 再次插入数据,预期队列大小=2,实际为1
    foo1.producer();
    // 读取队列,预期大小=2,实际为0
    foo2.consumer();

    return 0;
}

foo_2.h

#ifndef FOO_2_H
#define FOO_2_H

#include "shared_container.h"
#include <iostream>

class Foo2
{
  public:
    Foo2()
    {
    }

    static void consumer(void)
    {
        SharedContainer map = *g_map;
        // 读取预设key=1对应的队列
        auto node_q = &map[1];
        std::cout << "[consumer] size of queue=" << node_q->size() << std::endl;
    }
};

#endif    // FOO_2_H

foo_1.h

#ifndef FOO_1_H
#define FOO_1_H

#include "shared_container.h"
#include <iostream>

class Foo1
{
  public:
    Foo1()
    {
    }

    static void producer(void)
    {
        SharedContainer map = *g_map;
        // 向预设key=1对应的队列写入数据
        auto node_q = &map[1];
        // 向队列添加数据
        node_q->emplace(45);
        std::cout << "[producer] size of queue=" << node_q->size() << std::endl;
    }
};

#endif    // FOO_1_H

shared_container.h

#ifndef SHARED_CONTAINER_H
#define SHARED_CONTAINER_H

#include <memory>
#include <queue>
#include <unordered_map>

struct shared_container {
    int x;
    shared_container(int x)
    {
        this->x = x;
    }
};

using SharedContainer = std::unordered_map<int, std::queue<shared_container>>;
inline std::shared_ptr<SharedContainer> g_map = std::make_shared<SharedContainer>();

#endif    // SHARED_CONTAINER_H

编译运行结果

$ g++ -std=c++17 main.cpp -o test
$ ./test
[producer] size of queue=1
[consumer] size of queue=0
[producer] size of queue=1
[consumer] size of queue=0

问题原因

核心错误是每次操作的都是共享容器的副本,而非g_map指向的原容器:

  • 在main、producer、consumer中,都执行了SharedContainer map = *g_map;,这会创建g_map所指向容器的拷贝。
  • 生产者向副本的队列中添加数据,消费者读取的是另一个副本的队列,自然看不到数据;main里初始化的也是副本,和共享容器无关。
修复方案

直接操作g_map指向的原容器,通过指针或引用访问,避免拷贝:

修改后的代码

main.cpp

#include "foo_1.h"
#include "foo_2.h"

#include <iostream>

Foo1 foo1;
Foo2 foo2;

int main(int argc, char* argv[])
{
    std::queue<shared_container> q;
    // 直接操作g_map指向的原容器
    (*g_map)[1] = q;

    foo1.producer();
    foo2.consumer();

    foo1.producer();
    foo2.consumer();

    return 0;
}

foo_1.h

#ifndef FOO_1_H
#define FOO_1_H

#include "shared_container.h"
#include <iostream>

class Foo1
{
  public:
    Foo1()
    {
    }

    static void producer(void)
    {
        // 直接获取原容器的引用,避免拷贝
        SharedContainer& map = *g_map;
        auto& node_q = map[1]; // 用引用而非指针,更安全
        node_q.emplace(45);
        std::cout << "[producer] size of queue=" << node_q.size() << std::endl;
    }
};

#endif    // FOO_1_H

foo_2.h

#ifndef FOO_2_H
#define FOO_2_H

#include "shared_container.h"
#include <iostream>

class Foo2
{
  public:
    Foo2()
    {
    }

    static void consumer(void)
    {
        // 直接获取原容器的引用
        SharedContainer& map = *g_map;
        auto& node_q = map[1];
        std::cout << "[consumer] size of queue=" << node_q.size() << std::endl;
    }
};

#endif    // FOO_2_H

shared_container.h无需修改。

修复后运行结果

$ g++ -std=c++17 main.cpp -o test
$ ./test
[producer] size of queue=1
[consumer] size of queue=1
[producer] size of queue=2
[consumer] size of queue=2

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.20 15:33:26