Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the size of a class depends on the order of the member declaration? and How?

Tags:

Someone explain me how does the order of the member declaration inside a class determines the size of that class.

For Example :

class temp
{
public:
    int i;
    short s;
    char c;
};

The size of above class is 8 bytes.

But when the order of the member declaration is changed as below

class temp
{
public:
    char c;
    int i;
    short s;
};

then the size of class is 12 bytes.

How?

like image 819
Murugan Avatar asked May 09 '13 07:05

Murugan


People also ask

How do you determine a class size?

We also know that the class size is defined as the difference between the actual upper limit and actual lower of a given class interval. Therefore, the class size for the class interval 10-20 is 10.

What is the size of a class in programming?

The size of an empty class is not zero. It is 1 byte generally. It is nonzero to ensure that the two different objects will have different addresses.

What is the size of class in oops?

Explanation: Classes doesn't have any size, actually the size of object of the class can be defined. That is done only when an object is created and its constructor is called. 7.


2 Answers

The reason behind above behavior is data structure alignment and padding. Basically if you are creating a 4 byte variable e.g. int, it will be aligned to a four byte boundary i.e. it will start from an address in memory, which is multiple of 4. Same applies to other data types. 2 byte short should start from even memory address and so on.

Hence if you have a 1 byte character declared before the int (assume 4 byte here), there will be 3 free bytes left in between. The common term used for them is 'padded'.

Data structure alignment

Another good pictorial explanation

Reason for alignment

Padding allows faster memory access i.e. for cpu, accessing memory areas that are aligned is faster e.g. reading a 4 byte aligned integer might take a single read call where as if an integer is located at a non aligned address range (say address 0x0002 - 0x0006), then it would take two memory reads to get this integer.

One way to force compiler to avoid alignment is (specific to gcc/g++) to use keyword 'packed' with the structure attribute. packed keyword Also the link specifies how to enforce alignment by a specific boundary of your choice (2, 4, 8 etc.) using the aligned keyword.

Best practice

It is always a good idea to structure your class/struct in a way that variables are already aligned with minimum padding. This reduces the size of the class overall plus it reduces the amount of work done by the compiler i.e. no rearrangement of structure. Also one should always access member variables by their names in the code, rather than trying to read a specific byte from structure assuming a value would be located at that byte.

Another useful SO question on performance advantage of alignment

For the sake of completion, following would still have a size of 8 bytes in your scenario (32 bit machine), but it won't get any better since full 8 bytes are now occupied, and there is no padding.

class temp
{
public:
    int i;
    short s;
    char c;
    char c2;
};
like image 156
fkl Avatar answered Sep 20 '22 17:09

fkl


class temp 
{
public:
   int i;   //size 4 alignment 4
   short s; //size 2 alignment 2
   char c;  //size 1 alignment 1
}; //Size 8 alignment max(4,2,1)=4

temp[i[0-4];s[4-2];c[6-7]]] -> 8 Padding in (7-8)

class temp 
{
public:
    char c;  //size 1 alignment 1
    int i;   //size 4 alignment 4
    short s; //size 2 alignment 2
};//Size 12 alignment max(4,2,1)=4

temp[c[0-1];i[4-8];s[8-10]]] -> 12 Padding in (1-4) and (10-12)

like image 29
GutiMac Avatar answered Sep 20 '22 17:09

GutiMac