【问题标题】:c++ – Disappearing Variablec++ – 消失的变量
【发布时间】:2018-06-05 23:22:47
【问题描述】:

我正在编写一个函数来获取名为ab 的两个已排序vector<size_t>s 的交集。该函数遍历两个向量,从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 &lt; *aItr)b 似乎消失了。调试器似乎不知道b 甚至存在!当b 在返回到循环顶部后重新存在时,它现在已采用a 的值!

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

提前致谢!

【问题讨论】:

  • 旁注:如果你没有充分的理由自己做这一切,有far easier ways :)
  • 我会使用 std::set_intersection 除非将它写入一个我认为效率不高的新向量。
  • 相反。您的算法是二次的(因为您尝试从向量的中间删除,我不确定您是否甚至可以通过循环中的迭代器来执行此操作),而股票版本的复杂性将是线性的。一般来说,比起假设,更喜欢实际测量。假设经常是错误的。
  • @AriLevisohn,也许您正在使用优化进行编译,恰好从相关代码中完全删除变量 b (因为它在 begin() 之后从未使用过,并且相应的寄存器只是由其他值获取)。在调试之前尝试删除任何 -O 编译标志。
  • 调试优化代码时这种行为很正常 - 你是否开启了优化?

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


【解决方案1】:

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

在 StackOverflow 上查看:Iterator invalidation rules

当您擦除向量中的一个元素时,在删除点及以后的迭代器到该向量的迭代器不能保证是有效的。但是,您的代码假定 aEnd 具有这种有效性(感谢@SidS)。

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

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

【讨论】:

    【解决方案2】:

    您假设 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());
    }
    

    【讨论】:

      猜你喜欢
      • 2017-12-10
      • 2012-06-11
      • 2015-02-23
      • 2012-09-02
      • 1970-01-01
      • 1970-01-01
      • 2014-02-15
      相关资源
      最近更新 更多