struct结构体的大小

默认情况下,每个成员相对于结构体变量地址的偏移量正好是该成员类型所占字节的整数倍;且最终占用字节数为成员类型中最大占用字节数的整数倍。

struct A {
    int a;
    char b;
    short c;
};

A的大小为4+1+1(填充)+2=8
a的偏移量为0,占据4个字节。b的偏移量为4,占据1个字节。c的偏移量为6,占据2个字节。

struct B {
    char a;
    char b;
    char c;
};

B的大小为1+1+1+1(填充)=4
a的偏移量为0,占据1个字节。b的偏移量为1,占据1个字节。c的偏移量为2,占据1个字节。

struct C {
    char b;
    int a;
    short c;
};

C的大小为1+3(填充)+4+2+2(填充)=12
a的偏移量为0,占据1个字节。b的偏移量为4,占据4个字节。c的偏移量为8,占据2个字节。

#pragma pack(2)
    struct D {
    char b;
    int a;
    short c;
};

pragma pack(2)指明2字节对齐。则整体为2的整数倍。
D的大小为1+1(填充)+4+2=8
a的偏移量为0,占据1=2个字节。b的偏移量为2,占据4个字节。c的偏移量为6,占据2个字节。

struct A {
    int a;
    char b;
    short c;
};

struct B : A {
    char c;
    int d;
    short e;
};

当发生继承时,基类的算基类,其后填充不能被占用;子类算子类。

为什么需要字节对齐?

当CPU访问正确对齐的数据时,它的运行效率最高,当数据大小的数据模数的内存地址是0时,数据是对齐的。例如:WORD值应该是总是从被2除尽的地址开始,而DWORD值应该总是从被4除尽的地址开始。

数据对齐不是内存结构的一部分,而是CPU结构的一部分。当CPU试图读取的数值没有正确的对齐时,CPU可以执行两种操作之一:产生一个异常条件;执行多次对齐的内存访问,以便读取完整的未对齐数据,若多次执行内存访问,应用程序的运行速度就会慢。

C++类中的数据成员

1.在不考虑(或者说在没有)虚函数和虚继承的情况下,sizeof(自定义类)也按照类似上面的方式来计算。

2.如果一个类拥有虚函数或者虚继承,则在数据成员的基础上相当于多一个指针类型的数据成员(位置在所有数据成员的前面),最后计算时加上即可。

3.如果一个类或者结构体不含有任何数据成员,且无虚函数以及虚继承,则sizeof()结果为1。

4.静态成员不在计算范围。

class S {
};
// size = 1

class S {
    S() {}
    ~S() {}
};
// size = 1

class S {
    S() {}
    ~S() {}
    int a;
};
// size = 4

class S {
    S() {}
    ~S() {}
    virtual void fun() {}
    int a;
};
// size = 8
mm_struct 结构体是 Linux 内核中用来管理进程地址空间的数据结构,它的定义位于文件 include/linux/mm_types.h 中。 mm_struct 结构体包含了与进程内存管理相关的所有信息,例如进程虚拟地址空间的起始地址、结束地址、页表、内存映射等等。它的定义如下: ``` struct mm_struct { struct vm_area_struct * mmap; // 进程的内存映射区域链表 struct rb_root mm_rb; // 进程的虚拟地址空间红黑树 struct rw_semaphore mmap_sem; // 进程 mmap 操作的信号量 unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long); // 为进程映射新地址空间所使用的函数指针 unsigned long mmap_base; // 进程映射的基地址 unsigned long task_size; // 进程的虚拟地址空间大小 unsigned long highest_vm_end; // 进程虚拟地址空间中最高的地址 pgd_t *pgd; // 进程页表目录表 atomic_t mm_users; // 进程地址空间的使用计数 atomic_t mm_count; // 进程地址空间的引用计数 }; ``` 其中,各字段的含义如下: - mmap:进程的内存映射区域链表,用于存储进程的地址空间中各个区域的信息。 - mm_rb:进程的虚拟地址空间红黑树,用于存储进程地址空间中各个区域的信息,以便快速查找。 - mmap_sem:进程 mmap 操作的信号量,用于保护进程的内存映射区域链表,防止多个线程同时修改该链表。 - get_unmapped_area:为进程映射新地址空间所使用的函数指针,用于确定新映射的地址空间。 - mmap_base:进程映射的基地址,表示进程的虚拟地址空间中最小的地址。 - task_size:进程的虚拟地址空间大小,即进程可以使用的虚拟地址的范围。 - highest_vm_end:进程虚拟地址空间中最高的地址,即进程的虚拟地址空间的结束地址。 - pgd:进程页表目录表,用于存储进程的页表信息。 - mm_users:进程地址空间的使用计数,表示有多少个进程正在共享该进程的地址空间。 - mm_count:进程地址空间的引用计数,表示有多少个对象正在引用该进程的地址空间。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值