четверг, 28 октября 2010 г.

Выделение памяти в векторе

Всем привет
Решил сделать простенькую программу, которая бы наглядно показывала разницу между метода resize и reserve в классе vector из стандатной библиотеки.
Программа реализовалась за 10 минут:

#include "stdio.h"
#include "iostream"
#include "vector"
using namespace std;

int main()
{
std::vector intVector;
printf("Start: Size = %i, capacity = %i\n", intVector.size(), intVector.capacity());
intVector.resize(10);
printf("Resize 10: Size = %i, capacity = %i\n", intVector.size(), intVector.capacity());
intVector.reserve(25);
printf("Reseerve 25: Size = %i, capacity = %i\n", intVector.size(), intVector.capacity());

for(int i=0;i<16;i++)
{
intVector.push_back(i);
}
printf("Push_back: Size = %i, capacity = %i\n", intVector.size(), intVector.capacity());

return 0;
}

Все отлично работает. Красота.
А потом вспомнил, во всех книгах говорят о том, что размер вектора при добавлении новых элементов увеличивается в зависимости от некого коэффициента.
И решил, а давай ка проверю.
Проверяется очень просто переопределяем операторы new/delete и смотрим, сколько памяти реально выделяется при изменении размера вектора. Ниже код:

char mem[4096];
int startFreeBlock=0;

void* operator new(size_t blockSize);
void* operator new[](size_t blockSize);
void operator delete(void* block);
void operator delete[](void* block);

void* operator new(size_t blockSize)
{
int oldstartFreeBlock = startFreeBlock;
startFreeBlock += blockSize;
printf("New = %i, Adress = %i\n", blockSize, (int)(&mem[oldstartFreeBlock]));
return &mem[oldstartFreeBlock];
}
void* operator new[](size_t blockSize)
{
int oldstartFreeBlock = startFreeBlock;
startFreeBlock += blockSize;
printf("New = %i, Adress = %i\n", blockSize, (int)(&mem[oldstartFreeBlock]));
return &mem[oldstartFreeBlock];
}
void operator delete(void* block)
{
printf("Delete = %i\n", (int)(block));
}
void operator delete[](void* block)
{
printf("Delete[] = %i\n", (int)(block));
}

Код собрал и запустил под двумя компиляторами и вот результаты:

gcc-4.4.1:
Start: Size = 0, capacity = 0
New = 40, Adress = 4673568
Resize 10: Size = 10, capacity = 10
New = 100, Adress = 4673608
Delete = 4673568
Reserve 25: Size = 10, capacity = 25
New = 200, Adress = 4673708
Delete = 4673608
Push_back: Size = 26, capacity = 50
Delete = 4673708

Visual C++ 2008 Express:
Start: Size = 0, capacity = 0
New = 40, Adress = 4325880
Resize 10: Size = 10, capacity = 10
New = 100, Adress = 4325920
Delete = 4325880
Reseerve 25: Size = 10, capacity = 25
New = 148, Adress = 4326020
Delete = 4325920
Push_back: Size = 26, capacity = 37
Delete = 4326020

Как и ожидалось, в случае явной просьбы изменить размер вектора с помощью методов resize и reserve, приложение послушно все делает. Вектор увеличивается ровно до того размера, который я запросил. А вот в случае неявного изменения размера вектора при вызове метода push_back компиляторы делают это по разному. Компилятор gcc выделяет в два раза больше памяти чем Visual C++.

А константу, которая задает насколько больше будет вектор после отрабатывания push_back так и не нашел. Может кто знает, где ее найти, и можно ли ее изменять?

Всем доброй ночи.

Комментариев нет:

Отправить комментарий