Chinaunix首页 | 论坛 | 博客
  • 博客访问: 483269
  • 博文数量: 111
  • 博客积分: 2332
  • 博客等级: 大尉
  • 技术积分: 1187
  • 用 户 组: 普通用户
  • 注册时间: 2009-08-29 11:22
文章分类

全部博文(111)

文章存档

2013年(9)

2012年(28)

2011年(17)

2010年(28)

2009年(29)

我的朋友

分类: C/C++

2013-04-19 14:09:44

今天看unix网络编程,原始套接字部分,看到直接就把接收到的原始报文的数据放到了struct ip变量里面,所以就想知道C语言中如果直接给结构体变量的内存中赋上值,那结构体是怎样分割内存,给其中的各个变量的。

看了一下struct ip的定义,发现其中的字段顺序和ip报文中的各个顺序是一样的,所以就想结构体内各个变量的内存是按照他们在结构体中定义的顺序给分配的。

所以就写了个程序,测试了一下

点击(此处)折叠或打开

  1. #include
  2. #include
  3. #include
  4. #include
  5.  
  6. int main() {
  7.   struct test {
  8.     bool b1:1;
  9.     unsigned int i1:8;
  10.     bool b2:1;
  11.     unsigned int i2:6;
  12.   };
  13.   char *str = (char *)malloc(sizeof(char)*2);
  14.   *str = 'a';
  15.   *(str+1) = '0';
  16.   // p_test is aa converted into binary is 0 11000010 0 110000
  17.   struct test *p_test = (struct test*)(void *)str;
  18.   if ((p_test->b1 << 7) == 128)
  19.     printf("b1 is ture\n");
  20.   else
  21.     printf("b1 is false\n");
  22.   if ((p_test->b2 << 7) == 128)
  23.     printf("b2 is ture\n");
  24.   else
  25.     printf("b2 is false\n");
  26.   printf("p_test is %s\n", p_test);
  27.   printf("i1 is %u\n", p_test->i1);
  28.   printf("i2 is %u\n", (p_test->i2)<<2);
  29.   free(str);
  30. }

运行结果是:

b1 is ture
b2 is false
p_test is a0
i1 is 48
i2 is 48

然后我用gdb一步一步的查看,发现

点击(此处)折叠或打开

  1. (gdb) p p_test
  2. $1 = (struct test *) 0x601010
  3. (gdb) x/th 0x601010
  4. 0x601010: 0011000001100001
  5. (gdb) x/tb 0x601010
  6. 0x601010: 01100001
  7. (gdb) x/tb 0x601011
  8. 0x601011: 00110000

因为我制定了str所指内存的第一个地址放’a',第二个地址放’0′,所以0×601010这个地址的值是’a',0×601011这个地址的值是’0′。

不知道是因为我是malloc出来的内存,所以内存是在堆上的,由低地址往高地址涨,还是因为我用的系统是linux,小端字节序的。在给test结构体里面的各个变量分配内存的时候,是这么分的:

b1 分配0×601010指向内存的低地址的第一个位 即1,转换成十进制就是1

i1 分配0×601010指向内存的低地址的第二个位开始的后面7位,加上0×601011低地址的第一个位,i1即00110000,转换成十进制就是48

b2分配0×601011低地址的第二个位即0,转换成十进制就是0

i2分配0×601011低地址的第三个位开始往后的6位,即001100,i2 << 2,即00110000,转换成十进制为48

 

所以可以得出结论,C语言结构体中各个变量的内存分配是按照结构体定义的顺序来分配的。如b1就分配结构体的前1个bit,i1就分配结构体的第2到第9个bit的内存,b2就分配第10个bit的内存,i2就分配第10bit个后面的6个bit的内存。


==================================

又做了一下测试,把str的定义和初始化变成了这样的
char str[2] = {‘a’, ’0′};
这样就是在栈上分配内存了,发现不管是运行结果还是
b1 is ture
b2 is false
p_test is a0
i1 is 48
i2 is 48
而且内存中的数值也都是一样的
$1 = (struct test *) 0x7fffffffe410
(gdb) p x/th 0x7fffffffe410
No symbol “x” in current context.
(gdb)
No symbol “x” in current context.
(gdb) x/th 0x7fffffffe410
0x7fffffffe410: 0011000001100001
(gdb) x/tb 0x7fffffffe410
0x7fffffffe410: 01100001
(gdb) x/tb 0x7fffffffe411
0x7fffffffe411: 00110000
说明不是堆或者栈的问题。

阅读(1189) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~