结构体和共用体关于内存的分配问题
来源:互联网 发布:金妍儿 知乎 编辑:程序博客网 时间:2024/06/15 12:36
32位编译器:
char :1个字节
char*(即指针变量): 4个字节(32位的寻址空间是2^32, 即32个bit,也就是4个字节。同理64位编译器)
short int : 2个字节
int:
float:
double:
long:
long long:
unsigned long:
64位编译器:
char :1个字节
char*(即指针变量): 8个字节
short int : 2个字节
int:
float:
double:
long:
unsigned long:
结构体和共用体的内存分配是C语言的一个难点,也是面试题中的热点。
示例1:
点击(此处)折叠或打开
- Union data1
- {
- double d;
- int i;
- char c1;
- char c2[9];
- };
sizeof(union data1)的值为16.在编译器默认设置的情况下,该共用体最大基本类型为double,它占8字节,所以此共用体以8来对齐。字符数组c2占9个字节,那么整个共用体应该占9个字节,但按照对齐原则,实际分配给它的内存为16字节。
如果是:
点击(此处)折叠或打开
- struct data1
- {
- double d;
- int i;
- char c1;
- char c2[9];
- };
sizeof(struct data1)的值为24,首先按照存储大小,该结构体所占存储空间为:8+4+1+9=22字节,这个结构体也是以8对齐,因此实际分配的是24字节。
示例2:
点击(此处)折叠或打开
- Union data2
- {
- int i;
- char c1;
- char c2[9];
- };
sizeof(union data2)的值为12,该共用体占内存空间最大的基本数据类型为int,其长度为4,所以该共用体以4来对齐。该共用体的长度取决于字符c2,其长度为9,9不是4的倍数,要进行对齐,因此实际分配的存储空间为12.
点击(此处)折叠或打开
- struct data2
- {
- int i;
- char c1;
- char c2[9];
- };
sizeof(struct data2)的值为16,与上面共用体一样,该结构体以4对齐。按照存储大小,该结构体所占存储空间为:4+1+9=14,14不是4的倍数,进行对齐,对齐后的值为16.
示例3:
点击(此处)折叠或打开
- Union data3
- {
- char c1;
- char c2[3];
- };
sizeof(union data3)的值为3,该共用体占内存空间最大的基本数据类型为chart,其长度为1,所以该共用体以1来对齐。该共用体的长度取决于字符c2,其长度为3,因此分配的存储空间为3.
点击(此处)折叠或打开
- struct data3
- {
- char c1;
- char c2[2];
- };
sizeof(struct data3)的值为3,与上面共用体一样,该结构体以1对齐。按照存储大小,该结构体所占存储空间为:1+2=3字节。
示例4:
点击(此处)折叠或打开
- struct inner
- {
- char c1;
- double d;
- char c2;
- };
这个结构体显然是8字节对齐的,在给c1分配存储空间时,考虑到对齐,分配给c1的字节数就是8,然后给d分配8字节,最后给c2分配时,因为也要以8对齐,所以也分配了8个字节的存储空间。所以sizeof(struct inner)值为24.
如果是:
当然这个结构体也是以8字节对齐的,编译器编译程序时,给c1、c2分配存储空间没有必要各自给它们分配8字节,只要8字节就可以了。给d分配8字节,所以sizeof(struct inner)值为16.
点击(此处)折叠或打开
- struct inner
- {
- char c1;
- char c2;
- double d;
- };
点击(此处)折叠或打开
- struct inner
- {
- char c1;
- double d;
- char c2;
- };
- union data4
- {
- struct inner t1;
- int i;
- char c;
- };
由于data4共用体中有一个inner结构体,所以最大的基本数据类型为double,因此以8字节对齐。共用体的存储长度取决于t1,而t1长度为24,因此sizeof(union data4)的值为24.
点击(此处)折叠或打开
- struct inner
- {
- char c1;
- double d;
- char c2;
- };
- struct data4
- {
- struct inner t1;
- int i;
- char c;
- };
data4结构体中有一个inner结构体,所以以8对齐,变量i和c共分配8字节就可以了,因此sizeof(struct data4)的值为32.
示例5:
点击(此处)折叠或打开
- struct data
- {
- int a;
- long b;
- double c;
- float d;
- char e;
- short f;
- }d;
这个结构体所占的字节数是多少呢?这里假设long所占字节数为4字节,short占2字节。这个结构体与示例4中第二个struct inner类似。首先这个结构体是以8字节对齐的,因为最长基本数据类型为double,它占8字节,d、e、f、总和为7个字节。分配存储空间时,成员 a和b各分配4字节,d分配4字节,f分配2字节,e也分配2字节。d、e、f总和刚好占8个字节,所以sizeof(struct data)值为24.
点击(此处)折叠或打开
- struct data
- {
- int a;
- long b;
- double c;
- float d;
- char e[3];
- short f;
- }d;
sizeof(struct data)值为32.
例1:对于一个频繁使用的短小函数,在C语言中最好用什么实现?
答:最好用宏定义,这样可以节省调用函数的开销,效率最高。
例2:已知一个数组table,写一个宏定义,求出数组的元素个数
答:#define NTBL (sizeof(table)/sizeof(table[0]))
对于数组,sizeof(table)获取数组的总长度,而sizeof(table[0])是数组第一个元素所占的长度。当然若是可以用strlen()函数也行。
例3:给定结构
点击(此处)折叠或打开
- struct A
- {
- unsigned short t:4;
- unsigned short k:4;
- unsigned short i:8;
- unsigned long m;
- };
问sizeof(A)的值。
程序分析:unsigned short 一般占2个字节,unsigned long一般占4个字节,结构体A以4字节对齐,A中成员t、k、i共占4+4+8=16位,由于要内存对齐,实际那三个成员共占32位即4字节,成员m占4字节,因此sizeof(A)=8.
例4:求函数返回值,输入x=9999
点击(此处)折叠或打开
- int func(int x)
- {
- int count=0;
- while(x)
- {
- count ++;
- x=x&(x-1);
- }
- return count;
- }
程序分析:这是统计9999的二进制形式中有多少个1的函数。9999=9*1024+512+256+15,2*1024的二进制表示中含有1的个数为2;512的二进制表示中含有1的个数为1;256的二进制表示中含有1的个数为1;15的二进制表示中含有1的个数为4;故共有1的个数为8,结果为8 。1000(2)-1(2)=0111(2),正好是原数取反,用这种方法来求1的个数是高效率的。
例5:已知运行这个程序的主机中数据类型long占8字节,请分析程序的运行结果。
点击(此处)折叠或打开
- #include<stdio.h>
- int main()
- {
- struct data
- {
- long l;
- char *s;
- short int i;
- char c;
- short int a[5];
- }d;
- struct data *p=&d;
- printf("%d\n",sizeof(d));
- printf("%x\t%x\n",p,p+1);
- printf("%x\t%x\n",p,(char *)p+1);
- printf("%x\t%x\n",p,(long *)p+1);
- return 0;
- }
运行结果:
32
bffff60 bffff80
bffff60 bffff61
bffff60 bffff64
- 结构体和共用体关于内存的分配问题
- 结构体和共用体关于内存的分配问题
- 结构体与共用体的内存分配问题
- 共用体结构体的内存分配
- 结构体共用体内存分配问题
- 共用体和结构体内存分配
- 关于结构体的内存分配问题--sizeof(/*struct*/A)
- 共用体变量的内存分配
- new和delete对结构体分配内存的问题
- 结构体的内存分配问题
- iOS结构体的内存分配问题
- 关于结构体和共用体
- 关于结构体和共用体
- 结构体和类的内存分配
- 结构体和类的内存分配
- 结构和共用体
- 结构体的内存分配
- 结构体的内存分配
- onSaveInstanceState() 和 onRestoreInstanceState()方法
- 循环队列
- 再散列操作
- 编译qt-extended-4.4.3的时候出现问题解决办法
- 获取电脑硬件信息
- 结构体和共用体关于内存的分配问题
- 类集相关
- 聊天界面的制作(一)——基本布局的实现
- cat proc/version在内核中是如何实现的?
- java实现给一个文件重命名
- [盈利]移动APP盈利模式简述
- centos7 设置字体大小
- 聚簇索引和非聚簇索引
- LEETCODE-Ugly Number