原则
-
1.数据成员对⻬规则: 结构(
struct
)或联合(union
)的数据成员,第一个数据成员放在offset
为0
的地方,以后每个数据成员存储的起始位置要从该成员大小或者成员的子成员大小(只要该成员有子成员,比如说是数组,结构体等)的整数倍
开始(比如int
为4
字节,则要从4的整数倍地址开始存储。 -
2. 结构体作为成员: 如果一个结构里有某些结构体成员,则结构体成员要从其内部
最大
元素大小的整数倍
地址开始存储.(struct a
里存有struct b
,b
里有char
,int
,double
等元素,那b
应该从8
的整数倍开始存储.) -
3. 收尾工作: 结构体的总大小,也就是
sizeof
的结果,.必须是其内部最大成员
的整数倍
,不足的要补齐
。
示例
内存占用大小1.结构体内存大小
注:()
内为实际占用的位置。
struct Mystruct1 {
int a; // 4 (1 2 3 4)
char b; // 1 (5)
float c; // 4 6 7 (8 9 10 11)
double d;// 最大值 8 12 13 14 15 (16 17 18 19 20 21 22 23) 最大占用值的倍数补齐 所以是24
}Mystruct1;
struct Mystruct2 {
char c; // 1 (1)
int a; // 4 2 3 (4 5 6 7)
double b; // 最大值 8 (8 9 10 11 12 13 14 15) 补齐 16
}Mystruct2;
/// 结构体嵌套
struct Mystruct3 {
short a; // 2 (1 2)
bool b; // 1 (3)
struct Mystruct1 c; // 需要23 最大值为8,从8的整数倍开始。 4 5 6 7(8 9 10 ... 30)
float d; // 4 31 (32 33 34 35) Mystruct1中最大值8的倍数补齐 所以是40.
}Mystruct3;
验证结构体占用内存大小
2.OC对象内存大小
@interface CKPerson : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSString *nickName;
@property (nonatomic, assign) int age; // 4 字节
@property (nonatomic, assign) long height; // 8字节
@property (nonatomic) char c1; // 1字节
@property (nonatomic) char c2; // 1 字节
@end
@implementation CKPerson
@end
int main(int argc, const char * argv[]) {
@autoreleasepool {
CKPerson *person = [CKPerson alloc];
person.name = @"CCCK";
person.nickName = @"KC";
person.age = 55;
person.c1 = 'a';
person.c2 = 'b';
NSLog(@"%@",person);
}
return 0;
}
我们挨个打印下,查看内存地址打印结果。
0x001d8001000033c5
为 isa
指针,那么问题来了,age
、c1
、c2
的值储存在哪?答案是
0x0000001600006463
这里,但是打印出来书乱码,因为苹果对age
、c1
、c2
属性进行了重排
,通过4+1+1
的方式进行8字节对齐,不足补齐的方式储存在同一内存块
中,这样做的原因也是为了节省内存开销。
结果验证
0x00000016
对应 age= 22
, 0x64
对应ASCII码
值100
也就是 b
,0x63
对应ASCII码
值99
也就是 a
。
网友评论