c ++ - 消失的变量

时间:2018-06-05 23:22:48

标签: c++ pass-by-reference dynamic-memory-allocation

我正在编写一个函数来获取名为vector<size_t>a的两个已排序b的交集。该函数迭代两个向量,从a中删除b中不存在的任何内容,以便a中剩余的任何内容都是两者的交集。代码在这里:

void intersect(vector<size_t> &a, vector<size_t> &b) {
  vector<size_t>::iterator aItr = a.begin();
  vector<size_t>::iterator bItr = b.begin();
  vector<size_t>::iterator aEnd = a.end();
  vector<size_t>::iterator bEnd = b.end();

  while(aItr != aEnd) {
    while(*bItr < *aItr) {
      bItr++;
      if(bItr == bEnd) {
        a.erase(aItr, aEnd);
        return;
      }
    }
    if (*aItr == *bItr) aItr++;
    else aItr = a.erase(aItr, aItr+1);
  }
}

我收到了一个很大的错误。我正在踩调试器,一旦它通过第8行“while(*bItr < *aItr)b似乎消失了。调试器似乎不知道b甚至存在!当b返回到循环顶部后重新生成时,它现在采用a的值!

这是我期望在动态内存错误中看到的一种行为,但正如您所看到的,我在这里没有管理任何动态内存。我非常困惑,可以真正使用一些帮助。

提前致谢!

2 个答案:

答案 0 :(得分:3)

好吧,也许您应该首先解决代码的一个主要问题:迭代器失效。

请参阅StackOverflow上的Iterator invalidation rules

当您擦除向量中的元素时,在删除点处进入该向量的迭代器不会保证有效。但是,您的代码假定aEnd有效(感谢@SidS)。

我猜想这就是你所看到的原因,或者也许是你的编译器优化标志可以改变执行流程,不必要的变量的生命周期等等。

另外,作为@KT。注意,你的擦除可能非常昂贵,使你的算法在a。的长度上可能是二次时间。

答案 1 :(得分:1)

您假设b包含至少一个元素。要解决这个问题,您可以在第一次循环之前添加它:

if (bItr == bEnd)
{
    a.clear();
    return;
}

此外,由于您正在删除a中的元素,aEnd将无效。将aEnd的每次使用替换为a.end()

std::set_intersection可以为您完成所有这些:

void intersect(vector<size_t> &a, const vector<size_t> &b)
{
    auto it = set_intersection(a.begin(), a.end(), b.begin(), b.end(), a.begin());
    a.erase(it, a.end());
}