关于C语言内存占用

struct T {
    char a;
    int *d;
    int b;
    int c:16;
    double e;
};
T *p;

在64位系统以及64位编译器下,以下描述正确的是
A. sizeof(p) == 24
B. sizeof(*p) == 24
C. sizeof(p->a) == 1
D. sizeof(p->e) == 4

解析

也许很多同学选择了B,其实,我也选了这个。
但是,看了解析,我才发现,原来自己大意了。
因为,在64位系统下,地址占64位,即指针占64位,8个字节
所以,*p所占的内存是这要的:
a:本身占1个字节,字节对齐占7个字节,共8个字节
d:64位指针,占8字节
b:占32位,4个字节
c:16 :占16位,2个字节,字节对齐占2个字节,共4个字节
e:64位,8个字节
8 + 8 + 4 + 4 + 8 = 32

  • sizeof(p) == 8 P为指针,64位系统地址占8个字节
    sizeof(*p) == 24 根据内存对齐 32字节 a_ _ _ _ _ _ _ | * d 8字节| | b4字节| |c2字节|_ _ |e8字节|
    sizeof(p->a) == 1 正确
    sizeof(p->e) == 8 double

  • 字节对齐就是让每一个成员的开始地址是最大成员大小的整数倍,本题中最大的成员是e,占了8个字节,所以每一个成员的首地址都要是8的整数倍。
    a的首地址是0,是8的整数倍,为了确保后面一个成员开始的地址是8的整数倍,所以要填充7个字节;
    经过a的填充,d开始的地址是8的整数倍,不填充;
    b开始的地址是16,不需要填充;
    c占了2个字节,如果不填充那么下一个成员开始的地址是22,所以需要填充两个字节;
    e的首地址是24,本身是8个字节;
    所以加起来是32.

32位编译器
char :1个字节
char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节。同理64位编译器) 
short int : 2个字节
int:  4个字节
unsigned int : 4个字节
float:  4个字节
double:   8个字节
long:   4个字节
 long long:  8个字节
unsigned long:  4个字节
64位编译器
char :1个字节
char*(即指针变量): 8个字节
short int : 2个字节
int:  4个字节
unsigned int : 4个字节
float:  4个字节
double:   8个字节
long:   8个字节
long long:  8个字节
unsigned long:  8个字节
posted @ 2020-03-21 14:35  两小无猜  阅读(395)  评论(0编辑  收藏  举报