Sizeof, sizeof

Source: Internet
Author: User

Sizeof, sizeof
I. Reasons for the article-exploration of the migration of an interview question

I found that I have formed a habit of writing reasons. When I read my blog, I can recall why this problem occurs and how can I solve it, let's keep this habit. Today, the lab's sister-in-law is reading a book about sizeof. After discussing this question, I have always been convinced to answer the question, so I got this article. But it can only be called a small view, because it is impossible to summarize the usage of sizeof. You are welcome to add and discuss it.

2. Start with this question

I directly raised the key part of the problem:

string strArr1[] = { "Trend", "Micro", "Soft" };cout << "sizeof(strArr1) == " << sizeof(strArr1) << endl;

The answer in the book is as follows:

The strArr1 string consists of three segments. The sizeof (strArr1) is 12.
First, we need to make it clear that sizeof is neither a function nor an unary operator. It is a special keyword similar to macro definition,In particular, sizeof (string) = 4.

I don't know if you don't try this. Because there are so many compilers, how can the compiler know if it does anything?

Sure enough, in vs2013 release mode, the result is

Sizeof (string) = 24
Sizeof (strArr1) = 72

Debug mode

Sizeof (string) = 28
Sizeof (strArr1) = 84

It is also a 3x relationship, because this is a string array, which contains three string objects

So why does string have different results?

After reading the relevant information, we can conclude that char * must be 4 bytes. string may not only contain one char *, but also contain length information and other information, the implementation of string may be different in different databases, but the same point in the same database is that the sizeof () of string is fixed no matter how long it is stored in your string, the space occupied by the string is dynamically allocated from the heap and has nothing to do with sizeof.

Sizeof (string) = 4 may be one of the most typical implementations, but there are also library implementations where sizeof () is 12 and 32 bytes. However, after the VC6.0 test, sizeof (string) = 16. It is still related to the compiler.

To fully test some things, the more I test, the more I write, and then I came to the power enhanced version, see the code:

#include<iostream>using namespace std;int main(){    char p[] = { 'a', 'b', 'c', 'a', 'b', 'c' };    char *p1 = "abcabc";    char p2[] = "abcabc";    char p3[][2] = { { 'a', 'b' }, { 'c', 'a' }, { 'b', 'c' } };    printf("p == %s\n", p);    cout << p << endl;    cout << "sizeof(p) == " << sizeof(p) << endl;    cout << "sizeof(p1) == " << sizeof(p1) << endl;    cout << "sizeof(p2) == " << sizeof(p2) << endl;    cout << "sizeof(p3) == " << sizeof(p3) << endl;    cout<<"sizeof(string) == " << sizeof(string) << endl;    string strArr1[] = { "Trend", "Micro", "Soft" };    cout << "sizeof(strArr1) == " << sizeof(strArr1) << endl;    int a = 0;    cout <<"sizeof(a = 3) == " << sizeof(a = 3) << endl;    cout << "a == " << a << endl;    cout << "sizeof(999999) == " << sizeof(999999) << endl;    cout << "sizeof(9999999999999999999) == " << sizeof(9999999999999999999) << endl;    cout << "sizeof(9 / 5) == " << sizeof(9 / 5) << endl;    cout << "sizeof((double)9 / 5) == " << sizeof((double)9 / 5) << endl;    return 0;}

Running result:

Let me explain one by one what my tests are doing:
(1) first, this initialization method of p will not add '\ 0' at the end, so sizeof (p) = 6; and an interesting question is:The direct output p of printf and cout is different.Printf is about to come to the end of '\ 0'. I also read the assembly code of printf and cout, but I did not elaborate on it. Then I will study it in detail.
(2) the sizeof of p1 and p2 is different, because one is a pointer, the other is a character array, and the sizeof of pointer in Win32 compiling environment is 4, because it is a 4-byte address, 32bits addressable Space
(3) p3 is another interesting question,P3 cannot be written as p3 [3] [] for initialization.Because the number of rows in the two-dimensional array must be the same, that is, the two-dimensional array cannot be "uneven ".
(4) This is a trap

int a = 0;cout<<sizeof(a=3)<<endl;cout<<a<<endl;

Why is the output 4 or 0 instead of the expected 4 or 3 ??? It lies in the features of sizeof processing in the compilation phase. Because sizeof cannot be compiled into machine code, the content in the scope of sizeof is ().Cannot be compiledIs replaced with the type. = Operator returns the type of the left operand, so a = 3 is equivalent to int, and the code is replaced:

cout<<4<<endl;cout<<a<<endl;

Therefore, sizeof cannot support chained expressions, which is different from the unary operator.

Do not treat sizeof as a function, nor a mona1 operator, and treat it as a special compilation preprocessing.

(5) The reason is that 999999 is the number that a compiler can handle in int type, so it can be processed by int type. If it is too large, it cannot be done by int type, but 8 bytes can certainly be done.

Sizeof (999999) = 4
Sizeof (9999999999999999999) = 8

(6) Finally, I saw that (9/5) the compiler looked at it as an int, and it was the double type after forced conversion.

Iii. What is sizeof?

Sizeof is profound and profound. Even if I read a lot of information, it is impossible to finish the summary in one breath.

1. What is sizeof
First, let's take a look at The definition of sizeof on msdn: the sizeof keyword gives The amount of storage, in bytes, associated with a variable or a type (including aggregate types ). this keyword returns a value of type size_t. when I saw the word "return", did I think of a function? Wrong. sizeof is not a function. Have you ever passed parameters to a function without brackets? Sizeof is acceptable, so sizeof is not a function. Some people on the Internet say that sizeof is a unary operator, but I don't think so, because sizeof is more like a special macro, Which is evaluated during the compilation stage. For example:
Cout <sizeof (int) <endl; // the length of an int on a 32-bit machine is 4 cout <sizeof (1 = 2) <endl; // = The operator returns the bool type, which is equivalent to cout <sizeof (bool) <endl;
It has been translated:
cout<<4<<endl;cout<<1<<endl;
2. Syntax

Sizeof has three syntax forms:

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

Int I;
Sizeof (I); // OK
Sizeof I; // OK
Sizeof (int); // OK
Sizeof int; // error
Since writing 1 can completely replace writing 3, in order to unify the form and reduce the burden on our brains, there are 3rd writing methods. Forget it!

In fact, the size of the sizeof calculation object is also converted to the calculation of the object type, that is, the sizeof values of different objects of the same type are consistent. Here, the object can be further extended to the expression, that is, sizeof can evaluate an expression. The Compiler determines the size based on the final result type of the expression, and generally does not calculate the expression. For example:

Sizeof (2); // The type of 2 is int, so it is equivalent to sizeof (int );
Sizeof (2 + 3.14); // The type of 3.14 is double, and 2 is also upgraded to double, so it is equivalent to sizeof (double );

3. sizeof Function

Function Type

Consider the following questions:
Int f1 () {return 0 ;}; double f2 () {return 0.0 ;}void f3 () {}cout <sizeof (f1 () <endl; // The Return Value of f1 () is int, so it is considered intcout <sizeof (f2 () <endl; // f2 () returns double, therefore, it is considered a doublecout <sizeof (f3 () <endl; // error! Unable to use sizeofcout for void type <sizeof (f1) <endl; // error! Sizeof cout <sizeof * f2 <endl; // * f2 cannot be used for function pointers, which is equivalent to f2 (). Because it can be viewed as an object, parentheses are not necessary. Is considered double

Conclusion: When sizeof is used for a function, it will be replaced by the type of the function return value in the compilation phase.

4. sizeof of Array
char a[] = "abcdef";int b[20] = {3, 4};char c[2][3] = {"aa", "bb"};cout<<sizeof(a)<<endl; // 7cout<<sizeof(b)<<endl; // 20*4=80cout<<sizeof(c)<<endl; // 6

The size of array a is not specified during definition. The space allocated to it during compilation is determined according to the initialization value, that is, 7. C is a multi-dimensional array, and the space occupied is the product of each dimension, that is, 6. It can be seen that the size of the array is the space allocated during compilation, that is, the product of each dimension * the size of the array element.

Conclusion: The size of an array is the product of all dimensions * the size of an array element.

There is a trap:

int *d = new int[10];cout<<sizeof(d)<<endl; // 4

D is a dynamic array we often call, but it is actually a pointer, so the value of sizeof (d) is 4.
Consider the following questions:

double* (*a)[3][6];cout<<sizeof(a)<<endl;   // 4cout<<sizeof(*a)<<endl;   // 72cout<<sizeof(**a)<<endl; // 24cout<<sizeof(***a)<<endl; // 4cout<<sizeof(****a)<<endl; // 8

A is a very strange definition, which indicates a pointer to an array of the double * [3] [6] type. Since it is a pointer, sizeof (a) is 4.

Since a is a pointer of the double * [3] [6] type, * a indicates a multi-dimensional array of the double * [3] [6] type. Therefore, sizeof (*) = 3*6 * sizeof (double *) = 72. Similarly, ** a indicates an array of the double * [6] type, so sizeof (** a) = 6 * sizeof (double *) = 24. * ** A indicates an element, that is, double *. Therefore, sizeof (*** a) = 4. As for *** a, it is a double, so sizeof (*** a) = sizeof (double) = 8.

It is about to end. If you want to learn more, you need to read more information ~~~

-END-

References

[1] http://blog.csdn.net/freefalcon/article/details/54839
[2] http://www.cnblogs.com/wanghetao/archive/2012/04/04/2431760.html

Copyright statement: you are welcome to repost it. Just specify the source! If you do not like it, please leave a message to explain the reason and step on again. Thank you. I can also know the reason and keep improving !!

Related Article

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.