Miroslav Mares
Miroslav Mares

Reputation: 2392

C++ Dynamic allocation of vectors in vector?

I'm working with vector now and I have an interesting situation which I need to help with.

I have a vector of vectors, defined as following:

vector< vector<int> > list;

I am loading numbers from standard input using cin >> helpVar; and everytime when I get 0 (zero) I want to create new vector of ints, which will be put into this "main container" list.

Of course I don't know, how many times the zero number will appear - it's user-dependend. So I also don't know, how much vectors the program will add.

But I don't know, how exactly to do it. If I used C# or other garbage collection-like language, I would probably just write:

if(helpVar == 0)
{
   list.push_back(new vector<int>);
}

But this construction doesn't work in C++.

So my question is, how should I deal with this situation to make it working? Or am I just thinking about it wrong and it should be done in another way?

Thanks for the answers.

Upvotes: 3

Views: 3995

Answers (5)

Mike Seymour
Mike Seymour

Reputation: 254421

In C++11:

list.emplace_back();

In C++03:

list.push_back(std::vector<int>());

new dynamically allocates an object and gives you a pointer to it; vector::push_back() takes a reference to an object, which it will copy. Only use new when you want to dynamically allocate the object yourself - that's not necessary if you're using containers to do that for you. When you do use new, make sure you use a smart pointer (or very carefully written code) to delete it when you've finished with it.

Upvotes: 3

Giovanni Funchal
Giovanni Funchal

Reputation: 9170

Just do

list.push_back(vector<int>());

If you say "new", you are asking for space in the heap, but you don't need that. You already have space reserved in the outer vector! Just push a vector object (not pointer) and you'll be done!

Advanced: Note that this actually first constructs a new vector in the outer vector by growing its size by 1, then creates a new temporary vector in the stack, then copies the content of the later (empty, so nothing to do) to the first, then destroys the temporary vector in the stack. But the compiler will probably optimize this completely!

Upvotes: 1

Stephan Dollberg
Stephan Dollberg

Reputation: 34518

In C++ you can just do:

x.push_back(T);

Memory management is done by the class itself. I hope I did understand you right.

One thing you have to look for is, if the class you are pushing back has a default constructor declared.

Upvotes: 1

Vlad
Vlad

Reputation: 18633

You can

list.push_back(vector<int>());

in the beginning, add helpVar to the most recent vector by doing

list.back().push_back(helpVar);

and when you get a 0 just push back yet a new vector.

Upvotes: 1

James McNellis
James McNellis

Reputation: 354969

list.push_back(vector<int>());

vector<int>() creates a temporary vector<int> object and initializes it (i.e., it calls the default constructor for that object). push_back then copies that temporary object into the list.

In C# (and "other garbage collected languages"), new is used to create new objects, whose lifetimes are controlled by the garbage collector.

In C++, new is only used to dynamically allocate an object (and you are responsible for managing its lifetime, by using a smart pointer). The syntax T() (where T is the name of a type) is used to create a temporary object.

Upvotes: 7

Related Questions