什么是判断std :: vector是否已重置其数组的最佳方法?

时间:2012-02-22 18:10:19

标签: c++ pointers vector

我使用std::vector来存储一些对象数组,这些对象是由其他对象从向量外部引用的。我画了一个图表来更清楚地解释:

std::vector with objects being referenced

出于性能原因,我存储的是对象而不是指针。这些对象在我的游戏的每一帧都被排序,所以我希望数组具有良好的缓存属性。

当然,每当将对象添加到向量时,阵列都有可能被重置。在这种情况下,我的引用无效,需要更新。现在,为了检测重新安装,我使用以下方法:

size_t old_capacity = v.capacity();

// Do stuff that could change the vector's size
v.push_back(a);
v.push_back(b);
v.push_back(c);

if (old_capacity != v.capacity()) {
    update_references();
}

我的问题是:

  • 这是检测向量是否重新安置其数组的最佳方法吗?
  • 执行pop_back后,我还需要检查重新安装吗?

2 个答案:

答案 0 :(得分:2)

在我看来,最好的方法如下:只需使用指向矢量头部的指针即可。并非所有重新分配都会导致向量移动。

但是,我或多或少同意有关向量中引用的注释。此外,您可以使用std :: list,它不会出现重新分配的问题。

std::vector<int> v;

void *old_location = (void *) &(v.front());

v.push_back(3);
v.push_back(3);
v.push_back(3);

if (old_location != &(v.front()))
    update_references();

答案 1 :(得分:1)

正如您所正确指出的,每次向向量添加内容时,所有现有迭代器(和元素指针)都可能无效。虽然你可以尝试“检测”它,但我强烈建议以不同的方式解决问题。根据您的要求,您可以:

  • 使用索引而不是直接指针。代替 您Obj* ptr取消引用的*ptr, 您将size_t idx取消引用vector[idx]。 如果你已经有许多使用指针的现有代码,你可以尝试创建一个智能指针,这将在幕后做。

  • 如果添加,但永远不会从向量中删除项目,如果您不关心数据的连续性,则可能根本不想使用std::vector!我认为类似于一个块列表,每个块 - 例如 - 一个256个对象的固定数组就足够了。您将拥有缓存局部性(因为块不小于缓存行)和相对便宜的动态可扩展性。实际上,如果你的数组变长,它可能会更快地执行向量,因为它永远不会重新分配内存。

  • 如果您添加和删除项目,但是数据的排序和连续性很重要,您仍然可以使用块的列表,以及已删除对象的一些额外管理器,这将尝试在新的时候重用空白区域对象已添加。