Debug error: Vector iterator not dereferencable and Vector subscript out of range

时间:2015-06-15 15:00:03

标签: c++ vector stl iterator

I am trying to implement Rateless codes, but I have some issues in decoding. In the first implementation I used iterator to loop over a vector of vector and do some operation (like erase()) but I was getting this debug error: Vector iterator not dereferencable. After some googling I found this answer, so I switched from iterator to index, but I am facing the same problem and I do not know how to figure out. Now in debug mode I recive Vector subscript out of range.

Initialization of variables:

int k = 100;
int n = 150;
vector<int> output; // size of output is n
vector< vector<int> > relationship(n);
vector<int> decoded(k);
int counterDecodedSymbols = 0;
vector< vector<int> >::iterator it = relationship.begin();
vector<int>::iterator jt;
bool found = false;

First implementation with iterator:

    while (counterDecodedSymbols < k) {
    int counter0 = 0;
    for (it = relationship.begin(); it != relationship.end(); ++it) {       
        if (it->size() == 1) {
            ++counterDecodedSymbols;
            jt = it->begin();
            decoded[*jt] = output[it - relationship.begin()];
            found = true;
            break;
        }
        ++counter0;
    }

    if (!found) {
        break;
    }

    int counter1 = 0;

    for (vector< vector<int> >::iterator zt = relationship.begin(); zt != relationship.end(); ++zt) {
        for (vector<int>::iterator kt = zt->begin(); kt != zt->end(); ++kt) {
            if (it == relationship.end()) {
                cout << "Ops" << endl;
            }
            if (*kt == *jt && zt != it) {
                output[zt - relationship.begin()] ^= output[it - relationship.begin()];
                if (zt->size() != 1) {
                    kt = zt->erase(kt);
                }
                else {
                    zt = relationship.erase(zt)
                }
                break;
            }
        }
        if (zt == relationship.end()) {
            cout << "Ops" << endl;
        }
        ++counter1;
    }
    it = relationship.erase(it);
}

Second one implementation with index:

int it = 0;
int jt = 0;

while (counterDecodedSymbols < k) {
    for (it = 0; it < relationship.size(); ++it) {
        if (relationship[it].size() == 1) {
            ++counterDecodedSymbols;
            jt = relationship[it][0];
            decoded[jt] = output[it];
            found = true;
            break;
        }
    }

    if (!found) {
        break;
    }

    for (int zt = 0; zt < relationship.size(); ++zt) {
        for (int kt = 0; kt < relationship[zt].size(); ++kt) {
            if (relationship[zt][kt] == relationship[it][0] && zt != it) {
                output[zt] ^= output[it];
                if (relationship[zt].size() != 1) {
                    relationship[zt].erase(kt + relationship[zt].begin());
                }
                else {
                    relationship.erase(zt + relationship.begin());
                }
                break;
            }
        }
    }
    relationship.erase(it + relationship.begin());
}

I recive one error (in the first implementation) here for (vector< vector<int> >::iterator zt = relationship.begin(); zt != relationship.end(); ++zt) { With debugger I can see that zt size is 0, relationship size is 54 and counter1 (to see how many loop where done) is 55.

I recive a second one error (in the first implementation) here if (*kt == *jt && zt != it) { it size now is 0, relationship size is 33 and counter0 is 33.

So, the first time loop go over the size of it vector, and second time loop go over the size of zt vector. I think the problem is connected to erase method, but I do not know how to fix it.

After reading this post, I tried to switch to index, but the issue is not over, I recive one error here if (relationship[zt][kt] == relationship[it][0] && zt != it) { where it value is 149 and relationship size is 149.

I hope I was clear. Some one can put me in the right way?

1 个答案:

答案 0 :(得分:0)

只需要在

之后添加
if (!found) {
    break;
}

else {
    found = false;
}

如果it等于relationship.size(),则表示找不到任何一个项目。无论如何,found在每个for循环后都没有更新为false,因此如果它只找到一个项目,它会found = truefound保留值{{ 1}}即使在下一次迭代中没有找到任何其他项目。