Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ vector accessing elements

Tags:

c++

vector

How can I access elements from myVector like i would do with arrays ( for(i = 0; i < n; i++) cout << v[i] << " "; )

My code:

#include <iostream>
#include <vector>
#include <string>
using namespace std;

class Month
{
public:
    char *name;
    int nr_days;
    Month(char* c, int nr) : name(c), nr_days(nr){};
    ~Month() { /* free(name); */}
};

int main()
{
    Month January("January", 31);
    Month February("February", 28);
    Month March("March", 31);
    Month April("April", 30);
    Month May("May", 31);
    Month June("June", 30);
    Month July("July", 31);
    Month August("August", 31);
    Month September("September", 30);
    Month Octomber("Octomber", 31);
    Month November("November", 30);
    Month December("December", 31);

    vector<Month> *myVect = new vector<Month>;
    myVect->push_back(January);
    myVect->push_back(February);
    myVect->push_back(March);
    myVect->push_back(April);
    myVect->push_back(May);
    myVect->push_back(June);
    myVect->push_back(July);
    myVect->push_back(August);
    myVect->push_back(September);
    myVect->push_back(Octomber);
    myVect->push_back(November);
    myVect->push_back(December);

    for(vector<Month>::const_iterator i = myVect->begin(); i != myVect->end(); i++)
    {
        /*
        Month myMonth = i;
        cout << myMonth.name << " " << myMonth.nr_days << endl;
        */
    }

    free(myVect);
    return 0;
}

I would want to be something like a foreach algorithm: foreach(Month in myVect) cout << ...

And another question: why it gives me a run-time error at the destructor if I uncomment my line?

like image 796
Dementor Avatar asked Jan 25 '12 20:01

Dementor


1 Answers

Ok, there are a lot of problems here.

  1. You declare myVect as a pointer to a vector. This is unnecessary. One of the major benefits of using a vector is so that you don't have to worry about memory management as the vector does it for you. You stack allocate the vector, but internally it heap allocates the memory used to store the items it contains.

  2. You never initialize the pointer. You are invoking undefined behavior as that pointer is not valid. To initialize a pointer you use new. All you have is an invalid stack allocated pointer that does not point to a vector on the heap. EDIT: I just realized that the new was edited out, so you can disregard this one. Still, it shouldn't be a pointer at all.

  3. You are using free to deallocate a C++ class (that you never allocated to begin with...). Don't. This isn't C, you use new and delete to manage memory (when necessary!) in C++. free does not call destructors, it simply frees up a chunk of memory. delete on the other hand does as it knows how to deal with complex C++ types. Never mix new/delete with malloc/free.

  4. myVect->begin() returns a const_iterator, not a T (i.e., in this case, not a Month object). Dereferencing the iterator via the * operator will yield the current iteration object, so:


Month myMonth = *i  // <--- IMPORTANT!

As an aside, if you are going to be looping over the vector often you may want to typedef the iterator to reduce verbosity, i.e.,

typedef vector<Month>::const_iterator cmonth_iter;

Now you can write

for(cmonth_iter i = myVect.Begin(); i != myVect.end(); ++i )
{
    Month m = *i;
    // do stuff with m    
}
like image 67
Ed S. Avatar answered Oct 29 '22 02:10

Ed S.