一、sizeof
The return value of sizeof() is best saved with size_t. Under x86 and x64, this type has different representations, unsigned int
(32 bits), unsigned __int64
(64-bit)
#include <iostream> #include <string> #include <vector> int main() { int arrx[20]; auto n = _countof(arrx); //n = 20, the return value type is unsigned int. The macro _countf is defined in stdlib.h, c++ can also be used if the vector header file is included. //The type of sizeof return value is size_t, unsigned int (32 bits), unsigned __int64 (64 bits) char ch1[] = "HelloWorld"; char* ch2 = ch1; //sizeof(ch2) int arr1[] = { 1,2,3,4,5,6,7 }; int* arr2 = arr1; std::string str1 = "HelloC + + "; std::string str2; size_t s1 = sizeof(ch1); //11, "HelloWorld\0" is the space occupied by the memory, so it contains the last string end symbol \0, so it is 10 + 1=11 size_t s2 = sizeof(ch2); //Depends on the compiler platform, sizeof(ch2) gets the size of the pointer, x64 is 8, x86 is 4 size_t s3 = sizeof(str1); //sizeof(str) gets the size of the string object, which is a fixed value and has nothing to do with the specific content of str. size_t s4 = sizeof(str2); //64-bit: 40, 32-bit: 28 size_t s5 = sizeof(arr1); //28 An int occupies 4 bytes, 7*4=28 size_t s6 = sizeof(arr2); //The size of the pointer depends on the compiler platform, 32-bit: 4, 64-bit: 8 size_t s01 = sizeof((*ch1)); //1 size_t s02 = sizeof((*ch2)); //1 size_t s03 = sizeof((*arr1)); //4 size_t s04 = sizeof((*arr2)); //4 The size obtained by dereferencing is the size of the first element type char:1,int:4 size_t s7 = str1.length();//8, the length of the string, as many characters as there are, excluding the string terminator \0 size_t s8 = strlen(ch1); //10, strlen(str1) error, the parameter of strlen is const char*, the length of the string is as many characters as there are size_t s9 = str1.size(); //8, same as str.length(), size can also be used to obtain the size of the container std::vector<std::string> vec; vec.emplace_back("abcdef"); vec.emplace_back("123"); vec.emplace_back("qwert"); size_t s10 = vec.size(); //3 size_t s11 = sizeof(vec); //It has nothing to do with the number of elements, 64-bit: 32, 32-bit: 16, it should store four pointers (not sure) size_t s12 = sizeof(std::vector<bool>); //bool is 1/2 larger than other types, that is, 64:48, 32:24, size_t s13 = sizeof(std::vector<int>); //16,32 size_t s14 = sizeof(std::vector<std::string>); //16,32 size_t s15 = sizeof(std::vector<char>); //16,32 return 0; }
2. Byte alignment
#include <iostream> int main() { struct s1 //16 { int i; char c; double d; }; struct s2 //16 { double d; char c; int i; }; struct s3 //16 { char c; int i; double d; }; struct s4 //24 {//The type that takes up the largest space in the structure is 8(double), 1 + 7 + 8 + 4 = 20 is not a multiple of 8, so 4 bytes need to be filled to satisfy sizeof(double)=a multiple of 8 char c; double d; int i; }; std::cout << sizeof(s1) << sizeof(s2) << sizeof(s3) << sizeof(s4) << std::endl; #pragma pack(push) //Save the alignment status push and pop are a pair, there is no need to wrap them with push and pop, pack(n) will take effect on all subsequent sizeof #pragma pack(4) //Set to 4-byte alignment struct t1 { char m1; double m4; int m3; }; std::cout << sizeof(t1) << std::endl; //16 #pragma pack(pop)//Restore alignment state struct t2 { char m1; double m4; int m3; }; std::cout << sizeof(t2) << std::endl; //24 return 0; }
Three, string length
cstring header file (C-style string)
strlen(str) calculates the length of the string (returns the number of characters, excluding the ‘\0’ at the end)
string header file (std::string)
str.size() returns the length of the string (including the trailing null character, that is, spaces are also counted, there is no ‘\0’ at the end of the string type string)
CString header file (MFC)
str.GetLength() returns the number of characters (excluding the trailing null character)
Four. sizeof (common types)
1.sizeof(std::string)
Reprint: The layout of string in memory
Name | X86 (number of bytes) | X64 (number of bytes) |
---|---|---|
Allocator | 4 | 8 |
Original string Data position | 15 + 1, contains up to 15 characters plus a terminator ‘\0’ | 15 + 1, contains up to 15 characters plus a terminator ‘\0’ |
Character length Size | 4 | 8 |
Current capacity Capacity | 4 | 8 |
Total | 28 | 40 |
We will only discuss 32-bit programs below
- For strings 15 characters or less in length:
The data will be saved to a total of 16 bytes of Data. If string is a temporary variable, the entire string data is located on the stack.
- For strings with data larger than 15 characters:
An additional data area will be allocated on the heap, all data will be filled into the heap, and then the heap pointer will be assigned to the first pointer position of Data (the first 4 bytes of Data)
2.sizeof(container)
Container | x64 | x86 |
---|---|---|
deque | 40 | 20 |
vector | 32 | 16 |
3.sizeof(class)
class X{}; class Y : public virtual X {}; class Z : public virtual X {}; class A : public Y,public Z {}; sizeof(X) //1 sizeof(Y) //4 sizeof(Z) //4 sizeof(A) //8
X is 1 because the compiler has inserted 1 char into it, so that its object can have its own independent address Y in the memory. Z is because the pointer A of the virtual base class table contains Y and Z. 8
5. Some methods for getting the number of bytes or elements
_countof
windows macro, used to calculate the number of elements in a statically allocated array. The return value type is unsigned int, which must be statically allocated array, cannot be a pointer
char s1[] = "12345"; int s2[] = { 1,2,3,4,5 }; int* s3 = new int[10](); auto ret1 = _countof(s1); //6, including '\0' auto ret2 = _countof(s2); //5 //auto ret3 = _countof(s3); //error
offsetof
offsetof will generate an integer constant of type size_t, which is the byte offset of a structure member relative to the beginning of the structure. The members are given in member-designator and the name of the structure is given in type.
_msize
To obtain the actual size of the content pointed to by the pointer (not the size of the pointer), you can only obtain the size of the content pointed to by the pointer from new or malloc.
#include <iostream> void fun(int* p) { std::cout << sizeof(p) << '\ '; //8 (x64) std::cout << _msize(p) << '\ '; //40 = 4*10 } int main() { int* p = new int[10](); int p1[] = { 1,2,3 }; fun(p); //fun(p1); //It is not a pointer from new or malloc, the program will crash return 0; }