C++ sizeof (Part 1)

  • 2020-11-03 22:32:05
  • OfStack

sizeof is one of the operators in C/C++ (operator). Its function is to return the number of bytes of memory occupied by an object or type. It is frequently used, so you must have a comprehensive understanding of it.

1. Basic grammar of sizeof

sizeof has three grammatical forms.

[

(1) sizeof (object); / / sizeof (object);
(2) sizeof (type_name); / / sizeof (type);
(3) sizeof object; / / sizeof object;

]

Although the third grammatical structure is simple, it is not common, so it is recommended to use the first and second methods for simple unification 1.


int i;
sizeof( i ); // ok
sizeof i; // ok
sizeof( int ); // ok
sizeof int; // error

2.sizeof calculates basic types and expressions

sizeof calculates the size of an object by actually converting it to an object type; that is, different objects of the same type have an sizeof value of 1. Here, the object can be extended one step further to the expression, that is, sizeof can evaluate an expression, the compiler determines the size based on the final result type of the expression, sizeof is compile-time operation, independent of the runtime, and does not evaluate the expression. Consider the following code:


#include <iostream>
using namespace std;
int main(int argc,char* argv[])
{
cout<<"sizeof(char)="<<sizeof(char)<<endl;
cout<<"sizeof(short)="<<sizeof(short int)<<endl;
cout<<"sizeof(int)="<<sizeof(int)<<endl;
cout<<"sizeof(long)="<<sizeof(long int)<<endl;
cout<<"sizeof(long long)="<<sizeof(long int int)<<endl;
cout<<"sizeof(float)="<<sizeof(float)<<endl;
cout<<"sizeof(double)="<<sizeof(double)<<endl;
int i=8;
cout<<"i="<<i<<endl;
cout<<"sizeof(i)="<<sizeof(i)<<endl;
cout<<"sizeof(i)="<<sizeof(i=5)<<endl;
cout<<"i="<<i<<endl;
}

The results of running under Windows 64bits are as follows:

[

sizeof(char)=1
sizeof(short)=2
sizeof(int)=4
sizeof(long)=4
sizeof(long long)=4
sizeof(float)=4
sizeof(double)=8
i=8
sizeof(i)=4
sizeof(i)=4
i=8

]

There are two things to note when looking at this procedure.

(1) The value of i does not change, indicating that the expression in parentheses of sizeof has not been executed. sizeof calculates the type of the operation result of its expression at compile time, and the sizeof operation is independent of the runtime. sizeof(i) is equivalent to sizeof(int), and sizeof(i=5) is equivalent to sizeof(int), that is, the expression i=5 is not included in the executable code and is processed as early as compile time.
(2) Whether long int accounts for 8 bytes depends on the implementation of the compiler. The compiler used by Visual C++ in VS2012 is ES92en.exe. In Windows of 64bits, long is still compiled to 4 bytes.

3.sizeof calculates pointer variables

The pointer is the soul of C/C++, which records the address of 1 object. The bit width of a pointer variable is equal to the machine word length, which is determined by the number of registers in the CPU. On a 32-bit system, a pointer variable returns 4 bytes, and on a 64-bit system, the sizeof of a pointer variable returns 8 bytes.


char* pc = "abc";
int* pi=new int[10];
string* ps;
char** ppc = &pc;
void (*pf)(); //  A function pointer 
char testfunc()
{
return  ' k';
}
sizeof( pc ); //  The results for 4
sizeof( pi ); //  The results for 4
sizeof( ps ); //  The results for 4
sizeof( ppc ); //  The results for 4
sizeof( pf ); //  The results for 4
sizeof( &testfunc ); //  The results for 4
sizeof( testfunc ()); //  The results for 1
sizeof(*( testfunc) ()); //  The results for 1

After reviewing the above code, the following conclusions can be drawn:

(1) The sizeof value of pointer variable has nothing to do with the object type indicated by pointer, and has nothing to do with the amount of space requested by pointer. All pointer variables occupy the same amount of memory. Then why in native 64bits system, pointer variable size is still 4 bytes, because using 32-bit compiler to compile the program is 32 bits, so the pointer size is 4 bytes, you can modify the compiler version, do not repeat.

(2) & testfunc represents 1 function pointer, the pointer size is 4, so sizeof( & testfunc) = = 4. testfunc() represents 1 function call and the return value type is char, so sizeof(testfunc())==sizeof(char)==1. testfunc is itself a function pointer, so (*testfunc)() It's also one function call, sizeof((*testfunc)())==sizeof(char)==1 .

4.sizeof computes arrays

When sizeof operates on an array, it takes the size of all the elements of the array. Refer to the following code:


int A[3][5];
char c[]="123456";
double*(*d)[3][6];

cout<<sizeof(A)<<endl; // The output 60
cout<<sizeof(A[4])<<endl; // The output 20
cout<<sizeof(A[0][0])<<endl;// The output 4
cout<<sizeof(c)<<endl; // The output 7
cout<<sizeof(d)<<endl; // The output 4
cout<<sizeof(*d)<<endl; // The output 72
cout<<sizeof(**d)<<endl; // The output 24
cout<<sizeof(***d)<<endl; // The output 4
cout<<sizeof(****d)<<endl; // The output 8

After reviewing the above code, the following conclusions can be drawn:
(1) The data type of A is int[3][5] . A[4] The data type is int[5] . A[0][0] The data type is int. so


sizeof ( A ) ==sizeof(int[3][5])==3*5*sizeof(int)==60
sizeof(A[4])==sizeof(int[5])=5*sizeof(int)==20
sizeof(A[0][0])==sizeof(int)==4

although A[4] The sizeof operation, which is concerned only with data types, is completed at compile time.

(2) sizeof(c)=sizeof(char[7])==7 since the string ends with the null character '\0', char[7] ==7.

(3) d is 1 pointer, no matter what data type it points to, its size is always 4, so sizeof(d)==4. The data type of sizeof(*d) is double*[3][6] , so


sizeof(*d)==sizeof(double*[3][6])==3*6*sizeof(double*)==18*4==72

And similarly, we can extrapolate


sizeof(**d)==sizeof(double*[6])==6*sizeof(double*)==24
sizeof(***d)==sizeof(double*)==4
sizeof(****d)=sizeof(double)==8

What should be the values of i and j below when arrays are used as function parameters?


void foo1(char a1[3])
{
int i = sizeof( a1 ); // i == ?
}
void foo2(char a2[])
{
int j = sizeof( a2); // j == ?
}

Maybe when you try to answer j you realize that i got it wrong. Yes, i! = 3. Here the function parameter a1 is no longer an array type, but a pointer, equivalent to char* a1, why? If you think about it, when we call foo1, does the program allocate an array of size 3 on the stack? Don't! Arrays are "addressed" and callers only need to pass in the address of the argument, so a1 is naturally a pointer type (char*) and i has a value of 4, which is the same as j.

This is C++ sizeof (part 1) in detail. For more information on C++ sizeof, please follow the other articles on this site!


Related articles: