结构体、共用体和联合体位域分析存储的不同
2023-12-02 14:31:40
结构体、共用体和联合体位域分析存储的不同
结构体
结构体的存储方式非常简单,它是按照成员变量在结构体中声明的顺序依次存储的。例如,以下结构体:
struct student {
char name[20];
int age;
float gpa;
};
将在内存中存储为:
+------------------------+
| name[20] |
+------------------------+
| age |
+------------------------+
| gpa |
+------------------------+
共用体
共用体的存储方式与结构体不同,它只分配一个内存空间来存储所有成员变量。这意味着共用体中的成员变量是共享同一块内存空间的。例如,以下共用体:
union student {
char name[20];
int age;
float gpa;
};
将在内存中存储为:
+------------------------+
| name[20] / age / gpa |
+------------------------+
当我们访问共用体中的某个成员变量时,系统会根据当前存储在共用体中的数据类型来确定该成员变量在内存中的位置。例如,如果当前存储在共用体中的数据类型是name[20]
,那么当我们访问age
或gpa
时,系统会返回name[20]
的值。
联合体
联合体的存储方式与共用体相似,它也只分配一个内存空间来存储所有成员变量。但是,联合体与共用体的区别在于,联合体中的成员变量是按位存储的。这意味着联合体中的成员变量可以共享同一块内存空间,但它们不会相互覆盖。例如,以下联合体:
union student {
char name[20];
int age;
float gpa;
};
将在内存中存储为:
+------------------------+
| name[0] | name[1] | ... | name[19] | age[0] | age[1] | ... | age[3] | gpa[0] | gpa[1] | ... | gpa[3] |
+------------------------+
当我们访问联合体中的某个成员变量时,系统会根据当前存储在联合体中的数据类型来确定该成员变量在内存中的位置。例如,如果当前存储在联合体中的数据类型是name[20]
,那么当我们访问age
或gpa
时,系统会返回name[0]
到name[19]
的值。
isa分析,为何首地址不能直接po出类,原因是nonpointer_isa里面不止存储指向类对象的地址,还有其他数据
在isa分析中,首地址不能直接po出类的原因是nonpointer_isa里面不止存储指向类对象的地址,还有其他数据。这些数据包括:
- isa指针: 指向类对象的地址。
- 标志位: 用于标记对象的类型。
- 计数器: 用于记录对象的引用计数。
- 其他数据: 可能还包括其他数据,例如对象的哈希值等。
当我们使用po
命令来打印一个对象的地址时,系统只会打印出对象的isa指针。这是因为isa指针是唯一一个存储在nonpointer_isa中的指针。其他数据都是以二进制的形式存储的,因此无法直接打印出来。
如果我们想打印出对象的完整信息,我们需要使用p
命令。p
命令可以打印出对象的内存布局,包括所有存储在对象中的数据。例如,以下命令将打印出student
对象的所有信息:
p student
输出结果如下:
student = {
isa = 0x12345678,
flags = 0x00000000,
count = 1,
name = "John Doe",
age = 20,
gpa = 3.5
}
从输出结果中,我们可以看到student
对象的所有信息,包括isa指针、标志位、计数器、姓名、年龄和GPA。