2014-11-25 4 views
1

Мне нужно вычислить память (статическую и динамическую), принятую вектором myVec; я вычислил размер в следующем порядкеКак рассчитать размер вектора

size = sizeof(myVec) * myVec.size(); 

Мне нужно знать, что я сделал это правильно или нет?

struct S1 
{ 
    vector<int> v1; 
    IplImage* image; 
    vector<CvRect> rect; 
}; 

struct S2 
{ 
    vector<S1> var1; 
    vector<int> var2; 
    IplImage* img1; 
}; 

vector<S2> myVec; 


//size = sizeof(myVec) * myVec.size(); ????? 
+0

Статическая или динамическая память? – soon

+0

Статический и динамический – Deepak

+0

Не будет 'sizeof (myVec)' достаточно, поскольку он получает размер элементов в нем тоже .... ??? – Xlander

ответ

2

Вы не можете легко определить, как статический и динамический размер контейнера в C++, так как каждый содержал экземпляр может выделить свою собственную внутреннюю память (как отметил @enhzflep в комментариях).

Однако, если вам действительно нужно это сделать, и если вы знаете, какие типы вы хотите хранить в своем контейнере, вы можете использовать шаблоны для сборки окончательного алгоритма для вас. То есть, что-то вдоль линий:

template<typename T> 
struct compute_size { 
    static unsigned of(const T& t) { 
     assert(false && "not implemented"); 
     return 0; 
    } 
}; 

template<typename T> 
struct compute_size<std::vector<T>> { 
    static unsigned of(const std::vector<T>& v) { 
     // static size 
     unsigned result = sizeof(std::vector<T>); 
     // static and dynamic size of all used elements 
     for(auto& i : v) 
      result += compute_size<T>::of(i); 
     // account for allocated empty space 
     result += (v.capacity() - v.size()) * sizeof(T); 

     return result; 
    } 
}; 

template<> 
struct compute_size<int> { 
    static unsigned of(const int&) { 
     return sizeof(int); 
    } 
}; 

template<> 
struct compute_size<std::string> { 
    static unsigned of(const std::string& s) { 
     return sizeof(std::string) + s.capacity() * sizeof(std::string::value_type); 
    } 
}; 

Используется с помощью шаблона функции:

template<typename T> 
unsigned get_size(const T& val) { 
    return compute_size<T>::of(val); 
} 

приведшего к чему-то вроде:

std::vector<std::string> qqq; 
qqq.push_back("asdfasdf"); 
qqq.push_back("qwer"); 
std::cout << get_size(qqq) << std::endl; 

С некоторыми возможными оптимизациями, как:

// for PODs we don't really have to iterate 
template<> 
struct compute_size<std::vector<int>> { 
    static unsigned of(const std::vector<int>& v) { 
     return sizeof(v) + v.capacity() * sizeof(int); 
    } 
};  

И, возможно, обобщая это на целые группы типов, используя std::enable_if.

+0

Надеюсь, я не отвечаю на вопрос о домашнем задании ... –

+0

Я получаю следующую ошибку при компиляции выше кода, getmem.cpp: 4: 22: ошибка: ожидаемый инициализатор перед '<' токеном – Deepak

+0

Мне, вероятно, нужно знать, что такое в строке 4 вашего кода :) Однако вы правы, что код не компилируется - частичные специализации функций все еще не разрешены. Я исправлю ответ. –

0

Статический размер: sizeof(vector<S2>)

Динамический размер: myVec.capacity() * sizeof(S2)

+3

Nope. Попробуйте использовать ваш код, если 'S2' является' std :: string', например. Подсказка: результатом является количество элементов * sizeof ptr для строки. I.e 1 вектор-элемент, который содержит строковый объект, который содержит «индекс строки 0», производит выход 4 (динамический размер). – enhzflep

+0

@enhzflep Вы имеете в виду, что он не включает динамический размер 'std :: string'? – songyuanyao

+1

Yup, точно. Попробуйте следующее: 'typedef vector vecStr; vecStr myVec; myVec.push_back («Это элемент 0»); cout << "потребляемая память:" << myVec.capacity() * sizeof (string) << "bytes." << endl; 'Результат (в 32-битной проге в системе x64 win7) равен 4. – enhzflep

Смежные вопросы