Deepak
Deepak

Reputation: 1088

How to calculate size of a vector

I need calculate memory (static and dynamic) taken by the vector myVec; I have calculated the size in following manner

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

I need to know the what I did is correct or not ?

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(); ?????

Upvotes: 1

Views: 1233

Answers (2)

Martin Prazak
Martin Prazak

Reputation: 1605

You cannot easily determine both the static and dynamic size of a container in C++, because each contained instance can allocate its own internal memory (as @enhzflep pointed out in comments).

However, if you really need to do that, and if you know what types you might want to store in your container, you might use templates to assemble the final algorithm for you. I.e., something along the lines of:

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);
    }
};

Used via a function template:

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

Leading to something like:

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

With some possible optimisations like:

// 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);
    }
};    

And, possibly, generalizing this to whole groups of types using std::enable_if.

Upvotes: 2

songyuanyao
songyuanyao

Reputation: 172864

Static size : sizeof(vector<S2>)

Dynamic size : myVec.capacity() * sizeof(S2)

Upvotes: 0

Related Questions