I’d like to calculate the amount of memory in bytes that an object uses. Given
struct A
{
float data[16];
int index;
};
struct B
{
A a;
};
Is the following the correct way to do this?
template <class Type>
size_t footprint();
template <>
size_t footprint<A>()
{
return sizeof(float) * 16 + sizeof(int);
}
template <>
size_t footprint<B>()
{
return footprint<A>();
}
I’m not sure about footprint() since I’ve heard that compilers may add extra information just to store member variables, and I’m not sure about footprint() since it refers to a class object. Does that require some memory as well?
EDIT: Okay, say the situation changed such that we’re not using a static array but an actual pointer:
#include <iostream>
using namespace std;
struct A
{
A(int size_)
{
data = new float[size_];
size = size_;
}
~A()
{
delete [] data;
}
float* data;
int size;
};
struct B
{
B() : a(16) {}
A a;
};
size_t footprint(const A& a)
{
return sizeof(float) * a.size + sizeof(int);
}
size_t footprint(const B& b)
{
return footprint(b.a);
}
int main()
{
A a(16);
B b;
cout << "sizeof(A) = " << sizeof(A) << endl;
cout << "sizeof(B) = " << sizeof(B) << endl;
cout << "footprint(a) = " << footprint(a) << endl;
cout << "footprint(b) = " << footprint(b) << endl;
}
Here you would need to actually have a special sizeof function (here called footprint) right?
The correct way to do this is with
sizeof(A)orsizeof(B). Adding up the sizes of the members is not correct because the compiler is free to put in extra space, called padding, to properly align things.sizeofaccounts for this padding.You also expressed concerns over your array decaying into a pointer. This is not the case with
sizeof.sizeof(an array)will give the total number of bytes that array takes up, provided it is still in array form and hasn’t decayed into a pointer. The fact of the matter is that the standard explicitly disallows this decay to happen insizeof, so you’re safe there:C++11 N3485 § 5.3.3/4 [emphasis mine]:
sizeof(A) == 16 * sizeof(float) + sizeof(int) + sizeof(additional padding)