|
|
|||||||||
|
|||||||||
| |||||||||
|
|
|
| |||||||||
![]() |
|
|
«
Previous Thread
|
Next Thread
»
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
Clearing a vector without deleting the memory
Hello,
I am working with a large database table and I am reading data into a std::vector 100 records at a time. As such I'm declaring the vector as: Code:
std::vector<int> john(100); Is it possible to delete all the contents without releasing the memory? If not any improvement on? Code:
john.clear(); john.resize( 100 ); Thanks in advance, Patrick |
|
#2
|
||||
|
||||
|
If I were concerned about it, which I probably wouldn't be, I'd resize it once in the beginning and then just clear it thereafter. If I were REALLY concerned about it, I'd probably just use an array of 100 elements.
__________________
C/C++ pointers (Original in the "Commonly Asked Questions" thread). |
|
#3
|
||||
|
||||
|
Use memset() or std::fill() to set all the values to 0 (if you're using strictly ints).
|
|
#4
|
||||
|
||||
|
Quote:
This is probably the best idea because the standard doesn't specify if the object frees the memory or not upon the clear() and it is left to the implementor to decide upon this. You're guaranteed that the resize() will resize it to at least N elements (it may resize to more than N elements, or not resize at all if the size is already greater than N)
__________________
Up the Irons What Would Jimi Do? Smash amps. Burn guitar. Take the groupies home. "Death Before Dishonour, my Friends!!" - Bruce D ickinson, Iron Maiden Aug 20, 2005 @ OzzFest Down with Sharon Osbourne Puzzle of the Month solved by Keath and KevinADC, superior perl programmers of the month Looking for a perl job with kick-*** programmers in a well-known NASDAQ listed tech company with branches in the US and Europe? We're hiring. PM me for details. Requirements |
|
#5
|
||||
|
||||
|
One of the benefits of using STL containers is that they absolve you from much of the responsibility of memory management. You should generally trust it rather than try to second-guess it. The implementation is unlikely to release anything until destruction of the vector, and it certainly won't unnecessarily thrash memory to and from the heap.
Consider this: Code:
#include <vector>
#include <iostream>
using std::cin ;
using std::cout ;
using std::endl ;
int main()
{
std::vector<int> john(100);
cout << "Initial capacity = " << john.capacity() << endl ;
cout << "Initial size = " << john.size() << endl ;
cout << endl ;
john.clear() ;
cout << "Capacity after clear = " << john.capacity() << endl ;
cout << "Size after clear = " << john.size() << endl ;
cout << endl ;
john.resize(101) ;
cout << "Capacity after resize = " << john.capacity() << endl ;
cout << "Size after resize = " << john.size() << endl ;
cout << endl ;
john.resize(50) ;
cout << "Capacity after downsize = " << john.capacity() << endl ;
cout << "Size after downsize = " << john.size() << endl ;
cout << endl ;
cin.get() ; // wait
}
In MinGW/GCC I observed the following result: Code:
Initial capacity = 100 Initial size = 100 Capacity after clear = 100 Size after clear = 0 Capacity after resize = 101 Size after resize = 101 Capacity after downsize = 101 Size after downsize = 50 Code:
Initial capacity = 100 Initial size = 100 Capacity after clear = 100 Size after clear = 0 Capacity after resize = 150 Size after resize = 101 Capacity after downsize = 150 Size after downsize = 50 See that in both cases clear does not change the capacity (i.e. the allocated space for objects), it just calls each elements destructor and zeroes the object count. In both cases downsizing did not release any capacity. Also note that VC++ over allocates a marginal capacity demand, whereas in this simple example GCC did not. An algorithm making small incremental increases in size would be far less efficient in the MinGW case than VC++, but such an algorithm would be probably ill-advised in either case. Because std::vector elements are guaranteed to be contiguous, an increase in size that exceeds the capacity requires a new memory allocation and a copy of all elements - hence the benefit of over allocation; it decreases the number of memory allocations and times data must be moved. Note that vector::resize() creates or destroys elements and if necessary changes capacity. If you only wish to change capacity use vector::reserve() - this will ensure that a later resize will have enough storage in advance so you have reasonably fine control over when reallocation might occur, improving the determinism of the behaviour. Given the functionality required of the vector::reserve() function, it seems that regardless of whether the standard is explicit about it or not, the implication is IMO that capacity is never reduced. Either way std::vector has the necessary functionality to be able to test its behaviour on a particular implementation. Clifford Last edited by clifford : May 7th, 2008 at 05:22 PM. |
|
#6
|
|||
|
|||
|
Thanks everyone, particularly Clifford. I was assuming vector::size() does what vector::capacity() actually does.
Am I sweating the small stuff as suggested by sizeablegrin? If we're talking about a table with hundreds of thousands of small records is there any real benefit from worrying about memory allocation of the vector the records are read into? As it turns out using reserve() means there is no downside to worrying about it in this instance but I'd be interested in your opinions from a general point of view. I always think that it is worth sweating the small stuff so long doing so is relatively simple because lots of small things become a big thing... |
|
#7
|
||||
|
||||
|
Quote:
If you reserve the vector so that it never has to increase capacity, then there might be no benefit over an array. It would depend on whether you are going to take advantage of the 'value-added' features of STL containers provided by their member functions and the, STL algorithms library. Bear in mind that the interfaces of STL containers where possible are identical, so changing data structures when you realises you chose the wrong one is usually trivial. Clifford |
|
#8
|
||||
|
||||
|
Quote:
You say you're clearing the vector for each 100 elements read in. If you can't afford the allocation overhead of the vector, you probably can't afford any of the overhead associated with vectors. Use an array. Know your tools. Had you studied the vector's methods you would have seen the alternatives. In cases where things weren't explicitly laid out you could have run simple tests, as Clifford did. The time expended would have been considerably less then the time that has been spent using this means of research. Assuming that "size" was "capacity" is indicative of poor preparation. |
|
#9
|
|||
|
|||
|
Quote:
Unfortunately knowing that a function exists because you've read a reference (as I have) is very different from identifying the best methods to use in a particular circumstance - for that you need guidance (thank you again guys) or experience (of which I now have a little more). |
|
#10
|
||||
|
||||
|
Have the data be pointers to memory allocated on the heap. If you clear it will just clear the pointers and you'll have the memory still in tact.
You'll have to have something else still pointing to it to access it again though... |
|
#11
|
||||
|
||||
|
This fixes what, how?
![]() |
|
#12
|
||||
|
||||
|
Quote:
It is entirely unclear what you mean or why you think that a good idea, but where do you thing std::vector gets its data from in the first place? Besides the OP was worrying about something that does not actually happen in practice, so there is no problem to solve. I guess you didn't read the existing replies? Clifford |