Detailed description of the C + + sizeof operator and object size

Source: Internet
Author: User

Original: http://krystism.is-programmer.com/posts/41468.html

Learn c all know the sizeof operator. However, it is important to note the following points. Start with the C sizeof:

1. SizeOf is an operator, not a function. Although we are accustomed to sizeof (...), but () is not required, it simply represents a priority. We call the target object or operand behind sizeof. This convention is called the sizeof object.

2. When the object of sizeof is an expression, the size is the type size of the return value of the expression, but the value of the expression is not evaluated, such as

?
1234 charc = 1;inti = 2;cout << sizeof(c + i) << endl;cout << sizeof(c = c + i) << endl;

The former C + I converts an implicit type to an int type (type promotion), so it returns 4 (32-bit system), while the latter is converted to int, while the assignment to C is converted to char, so the return is 1. Similarly, if the object is a function, the return function returns the value type size, such as:

?
1234567891011 long long foo(){    printf("‘%s‘ has been called.\n", __func__);    return 0;}int main(int argc, char **argv){        cout << sizeof(foo()) << endl;    return 0;}

After execution output 8, will not output ' foo ' has been called. The description function is not actually executed, but only the next return type is judged.

3. Note that the sizeof object is the difference between a pointer and an array.

When sizeof's object is an array, the total size of the array is returned, and when the object is a pointer, the size of the pointer itself is returned, rather than the size of the memory space. Because the pointer itself is an unsigned integer, int *p, sizeof (p) returns the size of sizeof (void *), and the 32-bit system returns 4, or 32 bits. Note, however, that when an array masterpiece is passed into a function as an argument, it is automatically converted to a pointer type, as follows:

?
12345678910111213 void foo(int a[]){    cout << sizeof(a) << endl; /* 4 */}int main(int argc, char **argv){    int a[] = {1, 2, 3, 4};    int *p = a;    cout << sizeof(a) << endl; /* 16 */    cout << sizeof(p) << endl; /* 4 */    foo(a);    return 0;}

4. SizeOf cannot get the dynamically allocated memory size, that is, using malloc to dynamically allocate memory and not use sizeof to get its size.

5. Note that the C_style string ends with a \ End character and also takes up a char space, so sizeof ("1") returns 2. Instead, STRLEN returns the number of characters, not including the/s terminator.

6. About the structure type.

Theoretically, the space occupied by a struct is the sum of the total size of all members, but because of the alignment problem, there are padding bytes.

?
12345 structnode{    int a;    charc;};

The size is 8 bytes instead of 5 bytes and is populated with 3 bytes.

Note: The C-language hollow-struct size is 0, while the C + + hollow struct size is 1, depending on the discussion of empty classes later. In addition, the dynamic array behind the struct in C99, which is an array of unspecified size, does not include the size of the dynamic array when sizeof, i.e.

?
123456 structnode{    int a;    char c;    intd[];};

The return remains 8.

The following is a discussion of C + + classes. In addition to the struct, the above discussion about C's sizeof is also suitable for C + +. First of all, C + + in the struct type, note and C in the struct is not the same, C is a struct is a kind of basic data types to wrap a combination of types, and C + + 's struct is essentially a class, that is, a class of things, structs basically have, The struct also has constructors, destructors, member functions, and so on, but its default members are public, and class members defined by class are private by default. In addition, struct inheritance is public by default, whereas class-defined classes are private by default. Also note: Class can define template parameters, but struct cannot! Therefore, the struct is essentially a class.

The following is the main discussion of the class size:

1. The size of the empty class. An empty type instance does not contain any information and should be 0 in size. But when we declare an instance of that type, it must occupy a certain amount of space in memory, otherwise it will not be able to use these instances. The compiler determines how much memory is consumed. An instance of each empty type in the g++ occupies 1 bytes of space. Note that empty structs are empty classes, which is why C + + 's empty structs account for one byte.

2. Constructors, destructors, member function calls only need to know the address of the function, and the address of these functions is related to the type, and is independent of the specific instance, so no additional information is added to the instance.

3. Static data members are placed in global data members, which do not account for the class instance size, and there is only one entity for multiple class instances. Can be thought of as a special global variable.

All in all:

?
123456789 class A{    public:        static int a;        static char c;        A(){};        ~A(){};        void foo(){};};

The size of Class A is 1 bytes, equal to the empty class size, so static data member A,c and member functions do not occupy the size of the class.

4. A non-static data member of a class is similar to a struct in C, requires alignment, and may require a byte fill.

?
123456789 class A{    public:        int a;        char c;        A(){};        ~A(){};        void foo(){};};

The size of Class A is 8 bytes, and a occupies 4b,c of 1B, padding 3 b.

5. If there is a virtual function in a class, the type generates a virtual function table and adds a pointer to the virtual function table in each instance of the type, so the class size must be the space occupied by a pointer. In the case of normal inheritance, subclasses and base classes share this pointer.

?
12345678910 class A{    public:        int a;        char c;        A(){};        ~A(){};        void foo(){};        void virtual bar(){};};

The size of Class A is 12B. data member 8B, plus a pointer to the virtual function table. Note that it is on a 32-bit system. In the case of a 64-bit machine, a pointer takes up 8 B.

6. When virtual inheritance occurs, derived classes generate a pointer to the virtual base class table, which occupies a pointer size space. If there are virtual functions, do not increase the extra pointer size space, the reason is not very clear, if anyone knows, please tell me! As follows:

?
123456789 class a {      int A; class b: public virtual a { &NBSP;&NBSP;&NBSP;&NBSP; int B; &NBSP;&NBSP;&NBSP;&NBSP; virtual void foo () {};

The size of Class B is 12B, data member B is 4B, inherits a from a also accounts for 4B, the other one because of virtual existence, an additional pointer size 4B, total 12B. So: As long as there is virtual, either in the member function, or on the inheritance, add a pointer size space.

Basically on these, if there are flaws, please point out, thank you!

Detailed description of the C + + sizeof operator and object size

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.