Question: Do the following two structures print the same?

struct CJStruct1 {
    double a;
    char b;
    int c;
    short d;
}struct1;

struct CJStruct2 {
    double a;
    int b;
    char c;
    short d;
}struct2;

int main(int argc, char * argv[]) {
    NSString * appDelegateClassName;
    @autoreleasepool {
        
        NSLog(@"%lu-%lu",sizeof(struct1),sizeof(struct2));
        
        appDelegateClassName = NSStringFromClass([AppDelegate class]);
    }
    return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}
Copy the code

Output print:

According to? The two structures just have different positions of properties inside, so the print size is different, right?

Start with a memory map for the basic data types

Basic rules for memory alignment

  • The first member of the data member of a struct or union union starts offse = 0, According to specified number of memory size and how many (if the first member is a structure or consortium members have the maximum number of bytes in the future to calculate memory) in the back of the store of each member of the starting position for members of the member or members of the child the size of the integer multiple start (such as int is 4 bytes, will start from 4 integer times address storage. Min (current starting position mn)m=9n=4 9 10 11 12
  • If a structure has a substructure, then the first internal element of the substructure is stored from a multiple of the size of the largest element in the substructure (struct A has struct B and b has elements bool sub1, int sub2, double sub3). So the starting position should be a multiple of 8.
  • Finally, the sizeof the structure, sizeof(), must be a multiple of the sizeof the largest element in the structure.

From the above analysis, it can be seen that:

struct CJStruct1 { double a; // [0 8] -> 0.1.2.3.4.5.6.7 char b; // [8 1] -> 8 int c; // [12 4] -> 12.13.14.15 // 9.10.11 is not a multiple of 4. // [16 2] -> 16.17 The result is 24}struct1; struct CJStruct2 { double a; // [0 8] -> 0.1.2.3.4.5.6.7 int b; // [8 4] -> 8.9.10.11 char c; // [12 1] -> 12 short d; // [14 2] -> 14.15 The result is 16}struct2; Struct CJStruct3{bool c; // [0 1] -> 0 double a; // [8 8] -> 8.9.10.11.12.13.14.15 // Because 1.2.3.4.5.6.7 is not a multiple of 4 all from 12 int b; // [16 4] -> 16.17.18.19 struct CJStruct4{BOOL c; // [24 1] ->24 // According to the principle: the initial value of the substructure is a multiple of the largest element of the substructure, so (20.21.22.23) filter double a; // [32 8] -> 32.33.34.35.36.37.38,39 // 25.26.27.28.29.30.31 is not a multiple of 8. // [40 1] -> 40 }struct4; // Char d = 41->48; }struct3; // struct3; int main(int argc, char * argv[]) { NSString * appDelegateClassName; @autoreleasepool { NSLog(@"%lu-%lu-%lu",sizeof(struct1),sizeof(struct2),sizeof(struct3)); appDelegateClassName = NSStringFromClass([AppDelegate class]); } return UIApplicationMain(argc, argv, nil, appDelegateClassName); } 2021-06-08 20:27:52.248607+0800 structure in vivo alignment [3356:1718318] 24-16-56Copy the code

So let’s do one more piece of code

int main(int argc, char * argv[]) { NSString * appDelegateClassName; @autoreleasepool { CJPerson *p = [[CJPerson alloc]init]; p.name = @"CJ"; p.age = 18; P.ex = @" male "; P.h eight = 175.5; NSLog(@"% @\ n sizeof print: %lu\n class_getInstanceSize print: %lu\n malloc_size print: %lu",p,sizeof(p),class_getInstanceSize([CJPerson class]),malloc_size((__bridge const void *)(p))); appDelegateClassName = NSStringFromClass([AppDelegate class]); } return UIApplicationMain(argc, argv, nil, appDelegateClassName); }Copy the code

Conclusion:

  • sizeofThis returns the number of bytes of memory used by an object or typeBasic data types, objects, PointersAnd sizeof(p) is just the length of the pointer equal to 8
  • class_getInstanceSizeThe essence is to get at least the size of memory needed to create an object, 8-byte aligned.
  • malloc_sizeCalculate the objectThe actual distribution ofIs the size of memory that heap space is actually allocated to objects, and is 16-byte aligned.