C语言中的sizeof

转载 2015年07月11日 10:45:44
在CU的C/C++版看到一个例子:http://bbs.chinaunix.net/thread-3621056-1-1.html
  1. #include <stdio.h>

  2. struct A{
  3.         char a;
  4.         char b;
  5.         int c[0];
  6. };

  7. struct B{
  8.         char a;
  9.         char b;
  10.         int c;
  11. };

  12. int main()
  13. {
  14.         printf("sizeof(struct A): %d\n", sizeof(struct A));
  15.         printf("sizeof(struct B): %d\n", sizeof(struct B));

  16.         return 0;
  17. }
结果:
  1. digdeep@ubuntu:~/uulp$ gcc -Wall -o sizeof sizeof.c
  2. digdeep@ubuntu:~/uulp$ ./sizeof
  3. sizeof(struct A): 4
  4. sizeof(struct B): 8
  5. digdeep@ubuntu:~/uulp$
C语言在编译时的对齐规则:
1)找出struct 结果体中占用内存最大的类型(__alignof__(type)最大的类型),在struct A,struct B中都是int。
2)知道常识:编译指标器(#pragma pack(X),x86机器上默认X一般是4。
3)机器字长 (32位/64位)
注:有个容易误解的地方,占用内存最大的类型,不是指sizeof最大的那个,而是指__alignof__(type)最大的那个,double在32位上,可以为4和8,默认为4,可由编译参数控制,如果编译时加上-malign-double__aignof__(double)值由4变成了8。(一般除了double之外,其它的类型sizeof(type)  == __alignof__(type) )

比较三者,按照三者中
的来对齐。
因为__alignof__(int) == sizeof(int) == 4,所以struct A和struct B都是按照4字节对齐。
所以:sizeof(struct A) == 4, sizeof(struct B) == 8
在struct A中应该说int c[0]并不占用内存。也就是0长度的数组不占内存。
但是:数组长度虽然为0,但是却影响了结构体整体的对齐

一个类型的对齐值,可通过操作符__alignof__(type)得到
struct A{
      char a;
      char b;
      int a[0];
};
在编译器默认对齐方式的情况下,结构体内成员所在位置必须为其自身类型的整数倍,即short型必须在__aignof__(short) * n == 2n 的位置上开始存储。int 型必须在__aignof__(int)*n == 4n,double型必须在__aignof__(double)*n ==4n != 8n的位置上开始存储。而对于0长数组的情况,这个数组只是看上去在结构体里面,实际上并不能算是结构体的正式成员。
但是我们使用他的时候需要把他当做结构体的成员使用。

结构体 struct A 当中,由于最后一个成员是int c[0], 在为结构体分配空间时,按照int 类型对齐
假设 A.a地址为0xbfd1c, 则A.b地址为0xbfd1d, 则数组c的起始地址为0xbfd1d往后2位(按照int类型对齐),即为0xbfd20,但是c[0]不分配空间不占空间所以sizeof(A)=4
示例:
  1. #include <stdio.h>

  2. struct A{
  3.         char a;
  4.         char b;
  5.         double d;
  6. };

  7. int main()
  8. {
  9.         printf("sizeof(struct A): %d\n", sizeof(struct A));
  10.         return 0;
  11. }
编译运行结果:
  1. digdeep@ubuntu:~/uulp$ gcc -Wall -o sizeof sizeof.c
  2. digdeep@ubuntu:~/uulp$ ./sizeof
  3. sizeof(struct A): 12
  4. digdeep@ubuntu:~/uulp$ gcc -Wall -malign-double -o sizeof sizeof.c
  5. digdeep@ubuntu:~/uulp$ ./sizeof
  6. sizeof(struct A): 16
  7. digdeep@ubuntu:~/uulp$
可以看出,加了 -malign-double 选项时,结果为16,没有加 -malign-double 选项时,结果为12.
加了 -malign-double 选项时,强调按照double的sizeof(double)的大小来对齐。


在看一看几个例子:
  1. #include <stdio.h>

  2. struct A{
  3.         char a;
  4.         char b;
  5. };

  6. struct B{
  7.         char a;
  8.         char b;
  9.         double c;
  10. };

  11. struct C{
  12.         char a;
  13. };

  14. struct D{
  15.         char a;
  16.         short c[0];
  17. };

  18. struct E{
  19.         char a;
  20.         int c[0];
  21. };

  22. int main()
  23. {
  24.         printf("sizeof(struct A): %d\n", sizeof(struct A));
  25.         printf("sizeof(struct B): %d\n", sizeof(struct B));
  26.         printf("sizeof(struct C): %d\n", sizeof(struct C));
  27.         printf("sizeof(struct D): %d\n", sizeof(struct D));
  28.         printf("sizeof(struct E): %d\n", sizeof(struct E));

  29.         return 0;
  30. }
结果:
  1. digdeep@ubuntu:~/uulp$ gcc -Wall -o sizeof2 sizeof2.c
  2. digdeep@ubuntu:~/uulp$ ./sizeof2
  3. sizeof(struct A): 2
  4. sizeof(struct B): 12
  5. sizeof(struct C): 1
  6. sizeof(struct D): 2
  7. sizeof(struct E): 4

http://bbs.chinaunix.net/thread-3636905-1-3.html看到另一个与sizeof相关的问题:

2.某32位系统下, C++程序,请计算sizeof 的值(5分).
char str[] = “http://www.ibegroup.com/
char *p = str ;
int n = 10;
请计算
sizeof (str ) = ?(1)
sizeof ( p ) = ?(2)
sizeof ( n ) = ?(3)
void Foo ( char str[100]){
请计算
sizeof( str ) = ?(4)
}
void *p = malloc( 100 );
请计算
sizeof ( p ) = ?(5)

答:(1)25 (2)4 (3) 4 (4)4 (5)4
此题的关键是看:sizeof() 计算的到底是什么类型的变量的大小!!!
第一个sizeof(str),很明显str是将一个字符赋值给一个字符数组,所以答案应该是数组的大小。是25而不是24,因为最后还有结尾符:‘/0‘
第二个sizeof(p),很明显p是一个指针,所以在32为机器上大小为4字节
第三个sizeof(n),很简单,32为机器上int为4字节
第四个sizeof(str),应该注意该"str"是一个参数,我们知道C中数组作为参数,实际上传递的是数组的第一个元素的地址,所以"str"是一个指针,所以sizeof(str)等于4
第五个sizeof(p),p也是指针,所以大小为4.

这里特别要注意的是第一个和第四个!
第一个等于25而不是24要特别注意,因为是将一个字符串赋值给字符数组,而字符串是有结尾符的!!!
看下面代码的运行结果:
  1. #include <stdio.h>
  2. #include <stdlib.h>

  3. void foo(char str[100])
  4. {
  5.         printf("sizeof(str3): %d\n", sizeof(str));
  6. }

  7. int main()
  8. {
  9.         char str[] = "http://www.ibegroup.com/";
  10.         char str2[] = {'h', 't', 't','p',':','/','/',
  11.                         'w','w','w','.','i','b','e','g','r','o','u','p',
  12.                         '.','c','o','m','/'};
  13.         char *= str ;
  14.         int n = 10;
  15.         void *p1 = malloc(100);

  16.         printf("sizeof(str): %d\n", sizeof(str));
  17.         printf("sizeof(str2): %d\n", sizeof(str2));
  18.         printf("sizeof(p): %d\n", sizeof(p));
  19.         printf("sizeof(n): %d\n", sizeof(n));
  20.         printf("sizeof(p1): %d\n", sizeof(p1));
  21.         foo(str);

  22.         return 0;
  23. }
运行结果:
  1. digdeep@ubuntu:~/uulp$ ./sizeof
  2. sizeof(str): 25
  3. sizeof(str2): 24
  4. sizeof(p): 4
  5. sizeof(n): 4
  6. sizeof(p1): 4
  7. sizeof(str3): 4

相关文章推荐

解析C语言中的sizeof.docx

  • 2012年09月03日 14:29
  • 26KB
  • 下载

详细解析C语言中的sizeof

  • 2012年01月13日 19:43
  • 46KB
  • 下载

C语言 sizeof函数详解

sizeof,一个其貌不扬的家伙,引无数菜鸟竟折腰,小虾我当初也没少犯迷糊,秉着“ 辛苦我一个,幸福千万人”的伟大思想,我决定将其尽可能详细的总结一下。 但当我总结的时候才发现,这个问题既可以简单...

解析C语言中的sizeof.rar

  • 2007年11月27日 15:52
  • 2KB
  • 下载

C语言笔记:变量字节长度&取值范围——sizeof()VS strlen

sizeof():是运算符(operator),其作用就是返回一个对象或者类型所占的内存字节数。可用于任何变量名、类型名或常量值,当用于变量名(不是数组名)或常量时,它不需要用圆括号。C规定sizeo...

C语言中 sizeof 运算的值是在编译时还是运行时确定的?

在经典的《C语言程序设计》书中说到: C语言提供了一个编译时(compile-time) 一元运算符 sizeof,它可以用来计算任一对象的长度。 表达式 sizeof 对象 以及 siz...

c语言sizeof求结构体的大小

运算符sizeof可以计算出给定类型的大小,对于32位系统来说,sizeof(char) = 1; sizeof(int) = 4。基本数据类型的大小很好计算,我们来看一下如何计算构造数据类型的大小。...

C语言中sizeof求结构体大小(让你真正了解结构体成员在内存中的分布情况)

今天我在写程序的时候我发现当一个结构体里面的成员变量相同的时候但是顺序不同的时候,所消耗的内存大小是不一样的, 因为我对内存的消耗很敏感,我想它具体是怎么用的 ,于是我具体看了下关于结构体成员在内存...
  • yyfwd
  • yyfwd
  • 2016年03月14日 15:50
  • 2003

C语言中sizeof详解

1、什么是sizeof     首先看一下sizeof在msdn上的定义:     The sizeof keyword gives the amount of storage, in b...

C语言结构体 —— sizeof(struct)

这个内容也是很重要的一个,所以,这里对一些问题和规律做一个总结。 涉及到的几个概念: 内存对齐:      现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C语言中的sizeof
举报原因:
原因补充:

(最多只允许输入30个字)