Blade3
Blade3

Reputation: 4380

Reusing a vector in C++

I have a vector declared as a global variable that I need to be able to reuse. For example, I am reading multiple files of data, parsing the data to create objects that are then stored in a vector.

vector<Object> objVector(100);

void main()
{
    while(THERE_ARE_MORE_FILES_TO_READ)
    {
        // Pseudocode
        ReadFile();
        ParseFileIntoVector();
        ProcessObjectsInVector();
        /* Here I want to 'reset' the vector to 100 empty objects again */

    }
}

Can I reset the vector to be vector<Object> objVector(100) since it was initially allocated on the stack? If I do objVector.clear(), it removes all 100 objects and I would have a vector with a size of 0. I need it to be a size of 100 at the start of every loop.

Upvotes: 14

Views: 9625

Answers (10)

Maja Piechotka
Maja Piechotka

Reputation: 7216

Can I reset the vector to be "vector objVector(100)" since it was initially allocated on the stack?
  1. The C++ vectors are not allocated on stack. At least not directly. One of the parameters to vector (and other STL templates) is allocator. You can use pool allocators, heap allocators etc.

    The std::vector<T> is in fact nicely packed pointer to array with additional informations (such as size and capacity). Otherwise the size of vector had to be known in advance (which is not required).

  2. In fact in the example above the std::vector<T> is not on stack but in data section of program (or how is it called on non-ELF platforms).

So the question is if you need:

  • A vector of size 100. In this case, as it have been pointed out, it is likely that you are doing something strange. But it is still possible in nice way by resize method.
  • A vector of capacity 100. In this case you probably should not do anything as vectors do not shrink its capacity AFAIR. And for sure it is not required as vectors changes its capacity dynamically.

Upvotes: 0

Eclipse
Eclipse

Reputation: 45533

Why are you trying to reset a global variable? Just allocate a new vector each time through the loop, and pass the vector into the functions by reference.

void ParseFileIntoVector(vector<Object> &vector);
void ProcessObjectsInVector(const vector<Object> &vector);

int main() 
{ 
 while(THERE_ARE_MORE_FILES_TO_READ) 
 { 
     // Pseudocode 
     vector<Object> objVector(100); 
     ReadFile(); 
     ParseFileIntoVector(objVector); 
     ProcessObjectsInVector(objVector); 
 } 
}

Upvotes: 2

AshleysBrain
AshleysBrain

Reputation: 22591

Contrary to the other posts, the most efficient way to do this is probably this:

objVector.resize(0);
objVector.resize(100);

clear() frees the memory of the vector on some implementations (its only required postcondition is that size()=0). resize(0) maintains the capacity.

The swap trick also invokes an unecessary memory allocation. The temporary vector which you swap will allocate a new memory block, and after the swap the old memory block is released as well. Performance should be better without memory allocations.

Upvotes: 1

Dathan
Dathan

Reputation: 7456

Call objVector.clear() to remove previous data points, and then objVector.resize(100) to resize it to the appropriate size.

Note, though, that this is going to allocate 1 instance of Object using the default constructor, and then 100 copies of Object using the copy constructor, which may or may not be what you actually want. Optionally, if Object is a pointer type, you can use objVector.resize(100, NULL) to avoid possibly-unwanted allocations.

Upvotes: 0

Pratik Deoghare
Pratik Deoghare

Reputation: 37172

vector<Object> objVector(100); 

int main() 
{ 
 while(THERE_ARE_MORE_FILES_TO_READ) 
 { 
    // Pseudocode 
     ReadFile(); 
     ParseFileIntoVector(); 
     ProcessObjectsInVector(); 
     /* Here I want to 'reset' the vector to 100 empty objects again */ 
     objVector.clear();
     objVector.resize(100);

 } 
}

Upvotes: 4

RobK
RobK

Reputation: 1

Since you are using the default constructor for "Object", I think you should be able to rely on the vector's capacity instead of its size. So, when you call clear(), chances are you are not changing the capacity that was set by your vector constructor (you can hold at least 100 elements, they are already allocated). Read up on capacity, reserve, and size and how they each differ (reserve is the call you'd make to request changes of capacity, I'm just pointing it out in case you need it).

Anyway, though, if you need to reset your objects to the default state, rather than relying on the ability to do a vector-wide reset of the objects, you could also just make a call on your object called "reset" to set them to that state, and call it before you re-process using those same objects. Performance-wise, I don't see it as being any different, and code-wise it seems like a clean solution.

Upvotes: 0

UncleBens
UncleBens

Reputation: 41351

objVector.clear();
objVector.resize(100);

However, this is probably not recommended usage of vector. Are you quite sure you shouldn't be using push_back with a vector that is initially empty? How can you be sure that each file contains exactly 100 Objects, no more no less, as it appears from your question?

The vector probably doesn't need to be global either. Better to pass things around. When you see a bunch of functions called with no parameters, it is quite hard if not impossible to follow what is going on (because everyone else other than you - and including you when you come back to this code after a few months - will have no idea what these functions use for input and what is the output).

Upvotes: 6

Konrad Rudolph
Konrad Rudolph

Reputation: 545923

I have a vector declared as a global variable that I need to be able to reuse.

Why? It’s not clear from your code why the variable must be global. Why can’t you declare it inside the loop? Then you don’t need to reset it, this will be done automatically in each loop.

In order to access the variable from the other methods, pass it in as a parameter (by reference, so you can modify it). Having a global variable is rarely a good solution.

Something else: main must never have return type void, this is invalid C++ and many compilers will reject it.

Upvotes: 11

Jay Zhu
Jay Zhu

Reputation: 1672

The following code should do the trick.

vector<Object> temp(100);
objVector.swap(temp);

Upvotes: 1

Daniel Bingham
Daniel Bingham

Reputation: 12914

Call resize at the beginning or end of the loop: http://www.cplusplus.com/reference/stl/vector/resize/

That should do what you want. However, I would recommend using the push and pop functions instead. It is more space efficient and is how the Vector was intended to be used. The vector will expand and shrink as needed when you push (add) and pop (remove) items from it. That way you don't have to worry about the vector's size or contents. It simply becomes a processing queue.

Upvotes: 2

Related Questions