【问题标题】:Vector iterator not dereferencable error during push_back()向量迭代器在 push_back() 期间不可取消引用错误
【发布时间】:2019-05-26 23:52:44
【问题描述】:

以下代码在发布模式下有效,并且仅在调试模式下在 g_ItemList.push_back() 处引发错误,我浏览了一些 SO 帖子和论坛。有人提到"You can't iterate through a vector while pushing back, as push_back may invalidate iterators"。但对我来说还不清楚。有人可以解释它背后的逻辑以及如何解决这个问题吗?我正在使用 Visual Studio 2010 (v100) 编译程序

std::vector<class PPart> VECT_ITEMS;    
VECT_ITEMS g_ItemList;
g_ItemList.clear();

for (i = 0; i < n; i++)
    g_ItemList.push_back (temp[i]);     //where PPart *temp;

错误信息

【问题讨论】:

标签: c++ visual-studio-2010


【解决方案1】:

向量本质上是一个数组的包装器。给定的数组有一个特定的大小,向量的数据存储为这个数组的前n个元素,其中n是向量的大小,数组的大小大于等于n。当您调用push_back 并且向量在其内部数组中没有足够的空间时,它会创建一个更大的新向量(通常是现在大小不足的数组的两倍)并将所有向量元素复制到该数组之前删除旧的(这些数组存储在堆上并通过newdelete 创建)。

迭代器本质上是指向这个内部数组的指针¹。因此,当您调用 push_back 时,所有当前的迭代器都可能失效。这是因为可能已经创建了一个新数组,并且指向旧数组的指针指向现在释放的内存。从技术上讲,当您调用 push_back 然后取消引用在该调用之前创建的迭代器时,它是 undefined behavior

1:从技术上讲,它们是指向内部数组的指针的类包装器,但原则是两种方式。将它们仅视为指针通常是有用的,但并非总是如此。

【讨论】:

  • 那么在调试模式下没有办法修复这个错误吗?
  • @RobinAtTech 阅读我提供的关于未定义行为的链接对您很有用,因为即使在发布模式下也不安全。它最有可能在某天通过编译器更新、编译器切换、Windows 更新或其他任何数量的东西随意退出工作。另外,我只是重新阅读了您的代码,看起来我有点误解了它,因为它是MCVE。可以发一个吗?
猜你喜欢
  • 2015-08-07
  • 1970-01-01
  • 1970-01-01
  • 2014-12-26
  • 2015-01-13
  • 2015-07-03
  • 2018-02-01
  • 2013-06-03
  • 2013-06-05
相关资源
最近更新 更多