I have tested on stl vector with code below:
struct structA{
char charArray[256];
}
structA a;
..assign 256 characters to a.charArray
vector<structA> v1;
v1.reserve(1000);
for(int i=0; i<1000; i++){
v1.push_back(a);
}
I realized that for every 16 push_back, there is a spike in the v1.push_back. I suspect that there is a reallocation of memory. I am wondering why is it so since I already use the reserve? I tried to declared the vector using vectorv1(1000), it also gives the same behaviour.
By the way, if I increase the char into 512, it took just 8 push_back, 8 * 512 gives around 4k memory. Would that the 开发者_如何学Cissue related to memory paging?
Thanks.
Run this simple test and see if there are any allocations or deallocations you don't want or don't expect.
#include <iostream>
#include <vector>
#include <string>
#include <stdio.h>
#include <algorithm>
template <class T> class my_allocator;
// specialize for void:
template <> class my_allocator<void> {
public:
typedef void* pointer;
typedef const void* const_pointer;
// reference to void members are impossible.
typedef void value_type;
template <class U> struct rebind { typedef my_allocator<U> other; };
};
template <typename T> class my_allocator : public std::allocator<T> {
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
template <class U>
struct rebind {
typedef my_allocator<U> other;
};
my_allocator() throw()
{
}
my_allocator(const my_allocator& to_copy) throw()
{
}
template <class U>
my_allocator(const my_allocator<U>& to_copy) throw()
{
}
~my_allocator() throw()
{
}
pointer address(reference x) const
{
return std::allocator<T>::address(x);
}
const_pointer address(const_reference x) const
{
return std::allocator<T>::address(x);
}
pointer allocate(size_type s1, typename std::allocator<void>::const_pointer hint = 0)
{
size_t block_size = s1 * sizeof (T);
std::cout << "allocated, bytes: " << block_size << "\n";
return std::allocator<T>::allocate(s1, hint);
}
void deallocate(pointer p, size_type n)
{
size_t block_size = n * sizeof (T);
std::cout << "deallocated, bytes: " << block_size << "\n";
std::allocator<T>::deallocate(p, n);
}
size_type max_size() const throw()
{
return std::allocator<T>::max_size();
}
void construct(pointer p, const T& val)
{
std::allocator<T>::construct(p, val);
}
void destroy(pointer p)
{
std::allocator<T>::destroy (p);
}
};
struct structA{
char charArray[256];
};
int main()
{
structA a;
std::cout << "Test 1, with reserve\n";
{
std::vector<structA, my_allocator<structA> > v1;
v1.reserve(1000);
for(int i=0; i<1000; i++){
v1.push_back(a);
}
}
std::cout << "Test 1, done\n";
std::cout << "Test 2, without reserve\n";
{
std::vector<structA, my_allocator<structA> > v1;
for(int i=0; i<1000; i++){
v1.push_back(a);
}
}
std::cout << "Test 2, done\n";
return 0;
}
Your best bet is to fire up the debugger and "step into" reserve and see what's going on there - maybe your implementation of STL does nothing on reserve()
. Stepping into push_back()
won't hurt either - this way you will know exactly what's going one.
精彩评论