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

Elements inserted into map cleared after function executes

本文关键字:函数 执行 清除 元素 映射 插入      更新时间:2023-10-16

>我正在尝试创建一个函数,该函数将名为Project的自定义对象向量的元素转换为映射,其中"键"作为这些项目的ID,存储在成员变量中,以及项目本身的映射值。为此,我有一个简单的函数,它传递一个指向向量的指针作为参数,循环遍历(取消引用的)向量,并为每个元素检索其 ID 并使用 [ ] 映射运算符分配该对,如图所示。映射声明如下:

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]);
}
}

我遇到的问题是它在函数内部进行了正确的赋值(您可以在这张图片中的调试器中看到结果的样子),但是一旦函数退出,存储在对象中的所有数据就会重置为默认值,如下图所示。

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

提前感谢!

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

您应该弄清楚谁管理Project对象的生存期,以及是否需要复制它们以使它们保持活动状态。现在,vector始终管理生命周期,如果地图的寿命超过矢量,这将是一个问题。您可以将所有权共享给Project,可以转移函数中的所有权,也可以在函数中创建副本以分离生存期。前两个选项最好分别使用std::shared_ptrstd::unique_ptr来实现。