C++ accessing vector

2019-07-23 12:42发布

问题:

I have std::vector which contains my own class and I have to access its functions and voids.

class A
{
private: 
     int var;
     vector<string> vec;

public:
     void setVar(int i) { var = i; }
     void setVec(vector<string> a) { vec = a; }
};

I have also return functions but I didn't bother to type them. And I have included all necessary files.

int main()
{
    vector<A> vec;
    for (int i = 0; i < 10; i++)
    {
        A tmp;
        tmp.setVar(i);
        vec.push_back(tmp);
    }

    for (int i = 0; i < 10; i++)
    {
        vector<string> tmp;
        tmp.push_back("1");
        tmp.push_back("2");
        tmp.push_back("3");
        vec.at(i).setVec(tmp);  //Works sometimes or causes error std::out_of_range
        vec[i].setVec(tmp);     //Crashes the whole programm
    }
}

So how do I set those variables since the vector is initialized?

I am using g++ and this is not actual code because my actual code is messy.

Error for vec.at(i).setVec(tmp);
Error is:  terminate called after throwing an instance of 'std::out_of_range'
  what():  vector::_M_range_check

回答1:

Which compiler are you using ? I'm actually very surprised that std::vector<std::string> tmp("1","2","3"); even compiles !

To be honest I have no idea what it calls, but I bet that it doesn't do what you expect, which I believe is :

std::vector<std::string> tmp;
tmp.push_back("1");
tmp.push_back("2");
tmp.push_back("3");

For the record, boost.assign and C++0x provides the kind of container initialization you were trying to achieve.



回答2:

The code you posted still won't compile (no tmp declared in the first loop), so let me explain in general what happens.

There are two kinds errors you mentioned:

vec.at(i).setVec(tmp);  //Works sometimes or causes error std::out_of_range

The function at tries to be safe - it first checks the length of the vector, then returns the element of the given index, or throws std::out_of_range if the vector doesn't contain the element of such index.

The second case:

vec[i].setVec(tmp);     //Crashes the whole programm

Operator [] behaves much like the at() function for vectors, but it not "safe" as it does not do any bounds-checking. Therefore, if you try to access 4-th element of a 3-element, you just access some random place in your memory (could be another, unrelated variable, for example, could be anything else). If you're lucky, your program will crash after that. If you're unlucky, you'll have memory corruption issues and very strange bugs, hard to find.

The solution to your problem is:

a) Replace vec[i] with vec.at(i) - work the same (well, a tiny bit slower, but you won't feel that) and you're secure.

b) Then: Look at all the places when you actually do this vector lookup and in every place stop for a second and consider: "how big is this vector at this moment? am I sure that the element of this index exists?".

You're likely to find your bug quickly this way.



回答3:

I tried your code in VS2010 and was not able to reproduce the problem you described. Surely, passing vector by value is not a good idea, it should be a reference to a constant, but it cannot cause such error. Taking the fact that 'std::out_of_range' is raised, the most likely cause is that there is no element with such index in your vector. For testing, you can check if i < vec.size() before accessing vec[i] (or vec.at(i))



回答4:

I found problem. It was in function which handled the size of the vector. Apparently vector was empty. Dumb mistake. Thank you all for answers.



标签: c++ vector std