插入到映射中的元素在函数执行后清除

时间:2018-04-12 15:47:07

标签: c++ pointers dictionary vector

我正在尝试创建一个函数,该函数将名为Project的自定义对象矢量的元素转换为带有'键的地图。作为那些项目的ID,存储在成员变量中,以及项目本身的映射值。要做到这一点,我有一个简单的函数,它传递一个指向vector作为参数的指针,循环通过(解除引用的)向量,并为每个元素检索其ID并使用[] map运算符分配如图所示的对。地图声明如下:

map<int, Project*> unassigned_projects;

这是功能:

void Solution::setup_project_map(vector<Project>* project_list) {
    for (int i = 0; i != size(*project_list); ++i) {
        int project_id = (*project_list)[i].get_project_id();
        this->unassigned_projects[project_id] = &((*project_list)[i]);
    }
}

我遇到的问题是它在函数内部进行了正确的赋值(你可以看到调试器in this picture中的结果是什么),但只要函数退出所有数据存储在对象中会重置为默认值,如in this picture所示。

我的理解是,如果我将实际的矢量对象传递给函数,这将是有意义的,因为一旦函数完成,临时对象就会被删除,因此任何指向该对象元素的指针都会也变得未定义,或者如果我使用range-for循环并且它正在创建元素的副本。但是,由于我通过引用传递向量并在每个阶段直接解除引用,因此值应在函数内外保持不变。我过去曾遇到过没有正确使用传递参考的问题,所以我怀疑这是我在某种程度上出错的地方。

提前致谢!

1 个答案:

答案 0 :(得分:0)

您正在地图中存储指向Project的指针,但如果vector死亡(由于最终超出范围,我们无法从您的代码中告知发生的情况)那么每个Project也是如此。现在,地图中的所有指针都指向不再存在的Project。如果您尝试从死项目中读取,则会得到未定义的行为,并且调试器可能会显示垃圾或显示错误。

你应该找出谁来管理Project对象的生命周期,如果有必要复制它们是为了让它们保持活力。现在vector总是管理生命周期,如果地图比矢量长,这就是一个问题。您可以与Project共享所有权,您可以在函数中转移所有权,或者您可以在函数中创建副本以分隔生命周期。前两个选项最好分别使用std::shared_ptrstd::unique_ptr来实现。