【问题标题】:Why can't I set an iterator on a list in a vector?为什么我不能在向量中的列表上设置迭代器?
【发布时间】:2017-06-27 14:56:24
【问题描述】:

我有一个这样定义的列表向量:

std::vector<std::list<int>> lists;

我像这样将它传递给我的函数:

na.add(end, lists[i], end);

这是我将其传递给的函数:

// Adds values two lists, maintaining three digits per node
void add(std::list<int> &val1, std::list<int> &val2, std::list<int> &end) {
    std::list<int>::reverse_iterator rit1 = val1.rbegin();
    std::list<int>::reverse_iterator rit2 = val2.rbegin();
    int carry = 0;
    int sum;
    while (rit1 != val1.rend()) {
        sum = *rit1 + *rit2 + carry;
        carry = 0;
        if (sum / 1000 == 1) { // Carries values to keep nodes at 3 digits
            carry = 1;
            sum -= 1000;
        }
        end.push_front(sum);
        ++rit1;
        ++rit2;
        }

}

调试器正确地看到了列表,并为 end 设置了一个迭代器,但没有为 list[i] 设置一个迭代器。当传递单个列表时它工作正常,但不是一个包含在向量中的列表。

我做错了什么?

编辑:可重现的问题

#include "stdafx.h"
#include <list>
#include <iostream>
#include <math.h>
#include <iomanip>
#include <string>
#include <vector>


class NodeArithmetic {
private:
    int digit;

public:
    // Populates linked list with each node holding 3 digits
    void populateList(int x, std::list<int> &numbers){
    if (x >= 1000 || x <= -1000) {
        populateList(x / 1000, numbers); // Recursive function to grab chunks of 3 digits
    }
    digit = x % 1000;
    numbers.push_back(digit);
}
// Adds values two lists, maintaining three digits per node
void add(std::list<int> &val1, std::list<int> &val2, std::list<int> &end) {
    std::list<int>::reverse_iterator rit1 = val1.rbegin();
    std::list<int>::reverse_iterator rit2 = val2.rbegin();
    int carry = 0;
    int sum;
    while (rit1 != val1.rend()) {
        sum = *rit1 + *rit2 + carry;
        carry = 0;
        if (sum / 1000 == 1) { // Carries values to keep nodes at 3 digits
            carry = 1;
            sum -= 1000;
        }
        end.push_front(sum);
        ++rit1;
        ++rit2;
        }

}


};


int main()
{

std::list<int> end;
std::list<int> nums;
std::list<int> threeDigits;
std::vector<bool> signs;
std::vector<std::list<int>> lists;
std::list<int>::iterator it;
bool flag;
nums.push_back(3453);
nums.push_back(6454);
nums.push_back(-542);
nums.push_back(47842124);
it = nums.begin();
NodeArithmetic na;
while (it != nums.end()) {
    na.populateList(abs(*it), threeDigits);
    lists.push_back(threeDigits);
    threeDigits.clear();
    ++it;
}

for (int i = 0; i < lists.size(); i++) { // adds nodes of leading 0's
    for (int j = 0; j < lists.size(); j++) {
        while (lists[j].size() < lists[i].size()) {
            lists[j].push_front(0);
        }
    }
}
while (end.size() < lists[1].size()) {
    end.push_front(0); // nodes of leading 0's to results list
}

na.add(end, lists[0], end);
return 0;
}

【问题讨论】:

  • 我认为您在该特定行上传递列表的方式没有任何问题。问题可能出在您没有向我们展示的代码中。但请注意,val1val2 应由 const 参考,因为您不修改它们。
  • 请提供minimal reproducible example。您在此处显示的代码并不完整,因为其他人无法重现您遇到的错误
  • ...顺便说一句,您是否收到错误消息?如果是,是什么错误?
  • 添加了完整的代码。它说列表迭代器不可递减,但调试它看起来好像从未分配过。编辑:感谢您的提示-我会将它们更改为 const。
  • ...确定一步...这是完整的,但不是最小的。请删除与问题无关的任何内容(尤其是巨大的评论块不是问题的原因)

标签: c++ list vector stl


【解决方案1】:

问题实际上很简单:在add() 内部,您不断向val1 前面添加项目(通过end),因此while 循环永远不会终止,最终val2 用完项目。

考虑:

  • na.add(end, lists[0], end) 中,您通过引用传递第一个和第三个参数,因此在add() 中,&amp;val1 == &amp;end 是真的——也就是说,两个参数都引用同一个列表。
  • 您的循环尝试从val1 的末尾循环到val1 的开头。
  • 但是每次迭代,您都会调用 end.push_front(sum),它会在 end(与 val1 相同的列表)前面添加一个项目。
  • 因此,循环将永远不会终止,因为您不断将项目添加到您正在枚举的列表中。 rit1 永远不会等于 val1.rend()。 (因此,即使程序没有立即崩溃,它也会一直运行直到耗尽可用内存,然后然后它会崩溃。)
  • 此外,由于没有测试来查看rit2 是否等于val2.end(),所以val2 引用的列表中的项目用完了,因此出现“迭代器不可递减”错误。只要rit2 == val2.rend(),表达式*rit2++rit2 就会调用未定义的行为。

可能的解决方案:

  • 更改您的while 条件以额外测试rit2 != val2.rend()
  • 将不同的列表作为第三个参数传递给add()(如果这是add() 的先决条件,最好额外测试val1.size() == val2.size())。

【讨论】:

  • 完美!谢谢你。我没有想到这一点。现在,它在我只添加两个列表之前有效,因为这意味着 end 和 val1 是不同的列表。
猜你喜欢
  • 2021-03-10
  • 1970-01-01
  • 1970-01-01
  • 2017-09-24
  • 2012-02-25
  • 1970-01-01
  • 2011-04-16
  • 2012-04-22
  • 1970-01-01
相关资源
最近更新 更多