Dreading memory leaks, I would like to make sure I have an understanding of the following code:

//vector initialized to allocate 10 string objects
vector<string> *pvec1 = new vector<string>(10);
delete pvec1;

//10 vector<string> objects
vector<string> *pvec2 = new vector<string>[10];
pvec2[0].push_back("test1");
delete [] pvec2;

1> Would executing the preceding code create a memory leak? I am adding a string object to the first vector<string> object -- wouldn't that allocate more memory on the heap? If so, then wouldn't I have to execute: delete pvec[0]; ? Which doesn't work.

2> Is there a way to allocate (using new) 10 vector<string> objects, each with 10 string objects allocated? Such as: vector<string> **pvec2 = new vector<string>(10)[10]; ? Which also doesn't work.

Thanks!

Recommended Answers

All 7 Replies

Since you appear to be using STL vector objects you don't have to bother with memory allocation, it's done for you by the people who implement the vector class. So a vector sized to 10 objects of type T initially would be:

vector<T> myVector(10);

The need to get the vector of just the right size is minimal, given that it will expand on need of it's own accord, so unless you must give it size 10 initially, just let the implementation choose the default size for you:

vector<T> myVector;

and let it resize as it sees fit.

I always find vectors of vectors to be a bit confusing since I use them infrequently. I believe it's something like this:

vector< <vector<string> > 2dVectorOfStrings;

How you would size the inner vectors to 10 strings each and the vector of vectors to 10 inner vectors of 10 each would be pure conjecture, though I see no reason why you would even want to do so, other than as an educational experience.

//vector initialized to allocate 10 string objects
vector<string> *pvec1 = new vector<string>(10);
delete pvec1;

I am not sure what you mean by "allocate 10 string objects". There are no string objects here at all. This is just a special functionality of vectors that reserves enough space to hold 10 string objects without resizing.

1> Would executing the preceding code create a memory leak? I am adding a string object to the first vector<string> object -- wouldn't that allocate more memory on the heap? If so, then wouldn't I have to execute: delete pvec[0]; ? Which doesn't work.

No. The vector takes care of deallocating any memory it uses when it is destructed, which also destructs all the things in the vector. The string takes care of deallocating any memory it uses when it is destructed.

The "delete []" takes care of deallocating memory and destructing all the things in the array.

2> Is there a way to allocate (using new) 10 vector<string> objects, each with 10 string objects allocated? Such as: vector<string> **pvec2 = new vector<string>(10)[10]; ? Which also doesn't work.

Thanks!

No. Unfortunately, when you create an array of something in C++, it needs to have a default constructor, and all elements will be default-constructed. So you cannot use a custom constructor to construct elements of an array. This is related to the RAII idiom in C++, where everything has to be initialized when it is allocated; and in this case there is just not any convenient way to customly initialize elements of an array.

Commonly, people don't use arrays, and instead use vectors. They can then add elements to this vector individually, and have these elements be constructed by whatever constructor they choose.

For example, if you had a vector by value you would probably do this

vector<vector<string> > foo(10);
for (int i = 0; i < 10; i++)
    foo.push_back(vector<string>(10));

Or if you prefer dynamically allocating it, as from your post

vector<vector<string> > *bar = new vector<vector<string> >(10);
for (int i = 0; i < 10; i++)
    bar->push_back(vector<string>(10));

Or you can take the pseudo-Java approach, where everything is a pointer, so you can allocate the objects themselves at a separate time than the array itself

string** baz = new string*[10];
for (int i = 0; i < 10; i++)
    baz[i] = new string[10];
baz[4][2] = new string("hi");

vector< <vector<string> > 2dVectorOfStrings;

I do believe it is just:

vector <vector<string>> myvec;

How you would size the inner vectors to 10 strings each and the vector of vectors to 10 inner vectors of 10 each would be pure conjecture

You could do something like this:

vector <vector<string>> myvec(10, vector<string>(10));

This would initialize the vector to have 10 elements, where each element (being a vector itself) has 10 elements. Of course, like you mentioned, a vector will resize itself anyway, so not too big of a deal. Alternatively, you could set an optional "starting value" for each of the 10 inner elements:

vector <vector<string>> myvec(10, vector<string(10,"hello!"));

...this sets each inner vector element to "hello!". And you can access elements like any multi-D array...

myvec[outer_accessor][inner accessor];

though I see no reason why you would even want to do so, other than as an educational experience.

Well, perhaps you want to create a directed graph-like structure, except instead of each node pointing to only a few other nodes, each node in the structure is reachable from any other node (all interconnected).

So for example, suppose you had a vector of vectors, where each element (outer vector and inner ones) had 3 elements.

Call the outer vectors country nodes. Like Canada, U.S.A, and Mexico. Call the inner nodes city nodes. So within the Canada vector, you have 3 city vectors, Toronto, Vancouver, and Montreal. These represent a network of some kind, each having the ability to interact with each other, so you get a "cyclical" structure. Same for Mexico and US...

Anyway, you could probably develop your own struct that would better serve the purpose (especially in this scenario), but just an idea I guess. The cool thing about the vector is that it will add/resize the network. But again, you could develop your own struct...

> vector <vector<string>> myvec;
In the next C++ standard, yes. Right now the way the parsing rules work mean that >> is treated as a binary right shift instead of the closing character for a nested template. It's ugly, but you have to put a space between them for the code to compile:

vector <vector<string> > myvec;

> vector <vector<string>> myvec;
In the next C++ standard, yes. Right now the way the parsing rules work mean that >> is treated as a binary right shift instead of the closing character for a nested template. It's ugly, but you have to put a space between them for the code to compile:

vector <vector<string> > myvec;

vc++2008 Express compiles it ok without the space. But maybe that is just an implementation thing. Dev-C++ considers it an error.

Right, I was compiling on VC++ 08...I think it looks cleaner this way too.

Anyway, it didn't even cross my mind that it would be parsed as a binary shift...

And I actually meant that, in the original posting,

vector< <vector<string> > 2dVectorOfStrings;

there is an extra opening character. Thats more what I was getting at :S

> vc++2008 Express compiles it ok without the space.
VC++ 2005 compiles it too. Comeau doesn't when C++0x extensions are disabled, and that's a better measure of what's standard. Edward uses Visual Studio...I think Ed might start using that extension and claim C++0x conformance. ;)

> there is an extra opening character. Thats more what I was getting at
Haha! Ed missed that, sorry. :$

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.