Chinaunix首页 | 论坛 | 博客
  • 博客访问: 96967
  • 博文数量: 31
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 380
  • 用 户 组: 普通用户
  • 注册时间: 2014-02-24 22:04
文章分类

全部博文(31)

文章存档

2014年(31)

我的朋友

分类: LINUX

2014-08-08 17:06:36

原文地址:**C语言中的内存分配 作者:andyhzw

操作系统:ubuntu11.10
编译环境:gcc


代码段,只读数据段,读写数据段,未初始化数据段属于静态区域,而堆和栈属于动态区域。代码段,只读数据段和读写数据段将在连接之后产生,未初始化数据段将在程序初始化的时候开辟,而堆和栈将在程序的运行中分配和释放。


C语言程序分为映像和运行时两种状态,在编译连接后形成的映像中,将只包含代码段,只读数据段和读写数据段,在程序运行之前,将动态生成未初始化数据段,在程序运行时还将动态形成堆区域和栈区域。

1.代码段(code)
代码段由各个函数产生,函数的每一个语句将最终经过编绎和汇编生成二进制机器代码(具体生生哪种体系结构的机器代码由编译器决定)。


2.只读数据段(RO Data)
只读数据段由程序中所使用的数据产生,该部分数据的特点是在运行中不需要改变,因此编译器会将该数据段放入只读的部分中。C语言中的只读全局变量,只读局部变量,程序中使用的常量等会在编译时被放入到只读数据区。注意:
定义全局变量const char a[100]={"ABCDEFG"};将生成大小为100个字节的只读数据区,并使用“ABCDEFG”初始化。如果定义为:const char a[ ]={"ABCDEFG"};则根据字符串长度生成8个字节的只读数据段(还有’\0’),所以在只读数据段中,一般都需要做完全的初始化。


3.  读写数据段(RW Data)
读写数据段表示了在目标文件中一部分可以读也可以写的数据区,在某些场合它们又被称为已初始化数据段,这部分数据段和代码段,与只读数据段一样都属于程序中的静态区域,但具有可写性的特点。通常已初始化的全局变量和局部静态变量被放在了读写数据段,如: 在函数中定义static char b[ 100]={“ABCDEFG”};读写数据区的特点是必须在程序经过初始化,如果只定义,没初始值,则不会生成读写数据区,而会定位为未初始化数据区(BSS)。
如果全局变量(函数外部定义的变量)加入static修饰,这表示只能在文件内使用,而不能被其他文件使用。


4. 未初始化数据段(BSS)
与读写数据段类似,它也属于静态数据区,但是该段中的数据没有经过初始化。因此它只会在目标文件中被标识,而不会真正称为目标文件中的一段,该段将会在运行时产生。未初始化数据段只在运行的初始化阶段才会产生,因此它的大小不会影响目标文件的大小。

5.堆:堆内存只在程序运行时出现,一般由程序员分配和释放。在具有操作系统的情况下,如果程序没有释放,操作系统可能在程序(例如一个进程)结束后回收内存。

6.栈:栈内存只在程序运行时出现,在函数内部使用的变量、函数的参数以及返回值将使用栈空间,栈空间由编译器自动分配和释放。




测试实例:

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>

  4. const char ro_1[ ] = {"this is read only data"};         //只读数据区(rodata)

  5. static char rw_1[ ] ={"this is global read write data"};//已初始化读写数据段(data)

  6. char bss_1[ 100]; //未初始化数据段(bss)
  7. static    int bss_2;                        //未初始化数据段(bss)

  8. const char *rw_2 ="constant data"; //rw_2定义在已初始化读写数据段(data),字符串放在只读取数据段(rodata)
  9. const char *bss_3;                        //未初始化数据段(bss)

  10.  

  11. int main()

  12. {
  13.     short stack_short_1 = 9898; //定义在在栈(stack),占用2个字节

  14.     char stack_char_1[10];     //定义在在栈(stack)上开辟100个字节

  15.     char stack_char_2[ ]="abcdefg"; //s定义在在栈(stack),占用8个字节,“abcdefg”保存在s内存中

  16.     //定义在已初始化读写数据段(data),局部变量,只可在当前函数中使用
  17.     static char rw_3[ ]={"this is local read write data"};    

  18.     static char bss_4[100];     //定义在未初始化数据段(bss),局部变量,只可在当前函数中使用

  19.     static int rw_4 = 999;     //定义在已初始化读写数据段(data),局部变量,只可在当前函数中使用

  20.     const char stack_constchar_1[] = "hello world";//定义在在栈(stack),标识数组的数据不可更改
  21.     const int    stack_constint_1 = 666;//定义在在栈(stack),标识整形数据不可更改
  22.     const int *stack_constintptr_1;//定义在在栈(stack),标识指针指向的整形数据不可更改

  23.     char *stack_charptr_1;     //p1定义在在栈(stack),占用4个字节

  24.     char *stack_charptr_2="123456"; //p2定义在在栈(stack)上,
  25.                                     //p2指向的内容不能改,“123456”在只读数据区(rodata)

  26.     stack_charptr_1=(char *)malloc(10 * sizeof(char ) );     //分配内存区域在堆区(heap)

  27.     strcpy(stack_charptr_1,"xxxx"); //“XXXX”放在只读数据区(rodata),占5个字节

  28.     printf("global:\n");
  29.     printf("    rodata:\n");
  30.     printf("        ro_1 : %p,%s\n",ro_1,ro_1);
  31.     printf("        rw_2 pointto: %p,%s\n",rw_2,rw_2);

  32.     printf("    rwdata:\n");
  33.     printf("        rw_1 : %p,%s\n",rw_1,rw_1);
  34.     printf("        rw_2 define: %p\n",&rw_2);

  35.     printf("    bss:\n");
  36.     strcpy(bss_1,stack_char_2);
  37.     printf("        bss_1 : %p,size:%d,%s\n",bss_1,sizeof(bss_1),bss_1);
  38.     bss_2 = 7777;    
  39.     printf("        bss_2 : %p,size:%d,%d\n",&bss_2,sizeof(bss_2),bss_2);
  40.     bss_3 = stack_constchar_1;
  41.     printf("        bss_3 : %p,size:%d,point to :%p,%s\n",&bss_3,sizeof(bss_3),bss_3,bss_3);



  42.     printf("\nlocal:\n");
  43.     printf("    stack:\n");
  44.     printf("        stack_short_1: %p,%d\n",&stack_short_1,stack_short_1);
  45.     strcpy(stack_char_1,"333222111");
  46.     printf("        stack_char_1 : %p,%s\n",stack_char_1,stack_char_1);
  47.     printf("        stack_char_2 : %p,%s\n",stack_char_2,stack_char_2);
  48.     printf("        stack_charptr_1 define at: %p\n",&stack_charptr_1);
  49.     printf("        stack_charptr_2 define at: %p\n",&stack_charptr_2);

  50.     printf("        stack_constchar_1 : %p,%s\n",stack_constchar_1,stack_constchar_1);
  51.     printf("        stack_constint_1 : %p,%d\n",&stack_constint_1,stack_constint_1);
  52.     stack_constintptr_1 = &stack_constint_1;
  53.     printf("        stack_constintptr_1 : %p,%p,%d\n",&stack_constintptr_1,stack_constintptr_1,*stack_constintptr_1);

  54.     printf("    heap:\n");
  55.     printf("        stack_charptr_1 pointto: %p,%s\n",stack_charptr_1,stack_charptr_1);

  56.     printf("    rodata:\n");
  57.     printf("        stack_charptr_2 pointto: %p,%s\n",stack_charptr_2,stack_charptr_2);

  58.     printf("    rwdata:\n");
  59.     printf("        rw_3 : %p,%s\n",rw_3,rw_3);
  60.     printf("        rw_4 : %p,%d\n",&rw_4,rw_4);    

  61.     printf("    bss:\n");
  62.     printf("        bss_4: %p,%s\n",bss_4,bss_4);

  63.     free(stack_charptr_1);     //使用free释放p1所指向的内存

  64.     return 0;
  65. }

测试结果:


当前测试实例的各个段的大小以及分配情况:

点击(此处)折叠或打开

  1. t: file format elf32-i386

  2. Sections:
  3. Idx Name Size VMA LMA File off Algn
  4.   0 .interp 00000013 08048154 08048154 00000154 2**0
  5.                   CONTENTS, ALLOC, LOAD, READONLY, DATA
  6.   1 .note.ABI-tag 00000020 08048168 08048168 00000168 2**2
  7.                   CONTENTS, ALLOC, LOAD, READONLY, DATA
  8.   2 .note.gnu.build-id 00000024 08048188 08048188 00000188 2**2
  9.                   CONTENTS, ALLOC, LOAD, READONLY, DATA
  10.   3 .gnu.hash 00000020 080481ac 080481ac 000001ac 2**2
  11.                   CONTENTS, ALLOC, LOAD, READONLY, DATA
  12.   4 .dynsym 000000a0 080481cc 080481cc 000001cc 2**2
  13.                   CONTENTS, ALLOC, LOAD, READONLY, DATA
  14.   5 .dynstr 0000007f 0804826c 0804826c 0000026c 2**0
  15.                   CONTENTS, ALLOC, LOAD, READONLY, DATA
  16.   6 .gnu.version 00000014 080482ec 080482ec 000002ec 2**1
  17.                   CONTENTS, ALLOC, LOAD, READONLY, DATA
  18.   7 .gnu.version_r 00000030 08048300 08048300 00000300 2**2
  19.                   CONTENTS, ALLOC, LOAD, READONLY, DATA
  20.   8 .rel.dyn 00000008 08048330 08048330 00000330 2**2
  21.                   CONTENTS, ALLOC, LOAD, READONLY, DATA
  22.   9 .rel.plt 00000040 08048338 08048338 00000338 2**2
  23.                   CONTENTS, ALLOC, LOAD, READONLY, DATA
  24.  10 .init 0000002e 08048378 08048378 00000378 2**2
  25.                   CONTENTS, ALLOC, LOAD, READONLY, CODE
  26.  11 .plt 00000090 080483b0 080483b0 000003b0 2**4
  27.                   CONTENTS, ALLOC, LOAD, READONLY, CODE
  28.  12 .text 0000052c 08048440 08048440 00000440 2**4
  29.                   CONTENTS, ALLOC, LOAD, READONLY, CODE
  30.  13 .fini 0000001a 0804896c 0804896c 0000096c 2**2
  31.                   CONTENTS, ALLOC, LOAD, READONLY, CODE
  32.  14 .rodata 00000282 08048988 08048988 00000988 2**2
  33.                   CONTENTS, ALLOC, LOAD, READONLY, DATA
  34.  15 .eh_frame_hdr 00000034 08048c0c 08048c0c 00000c0c 2**2
  35.                   CONTENTS, ALLOC, LOAD, READONLY, DATA
  36.  16 .eh_frame 000000c4 08048c40 08048c40 00000c40 2**2
  37.                   CONTENTS, ALLOC, LOAD, READONLY, DATA
  38.  17 .ctors 00000008 08049f14 08049f14 00000f14 2**2
  39.                   CONTENTS, ALLOC, LOAD, DATA
  40.  18 .dtors 00000008 08049f1c 08049f1c 00000f1c 2**2
  41.                   CONTENTS, ALLOC, LOAD, DATA
  42.  19 .jcr 00000004 08049f24 08049f24 00000f24 2**2
  43.                   CONTENTS, ALLOC, LOAD, DATA
  44.  20 .dynamic 000000c8 08049f28 08049f28 00000f28 2**2
  45.                   CONTENTS, ALLOC, LOAD, DATA
  46.  21 .got 00000004 08049ff0 08049ff0 00000ff0 2**2
  47.                   CONTENTS, ALLOC, LOAD, DATA
  48.  22 .got.plt 0000002c 08049ff4 08049ff4 00000ff4 2**2
  49.                   CONTENTS, ALLOC, LOAD, DATA
  50.  23 .data 00000050 0804a020 0804a020 00001020 2**2
  51.                   CONTENTS, ALLOC, LOAD, DATA
  52.  24 .bss 00000128 0804a080 0804a080 00001070 2**5
  53.                   ALLOC
  54.  25 .comment 0000002a 00000000 00000000 00001070 2**0
  55.                   CONTENTS, READONLY
  56.  26 .debug_aranges 00000020 00000000 00000000 0000109a 2**0
  57.                   CONTENTS, READONLY, DEBUGGING
  58.  27 .debug_info 0000026e 00000000 00000000 000010ba 2**0
  59.                   CONTENTS, READONLY, DEBUGGING
  60.  28 .debug_abbrev 00000094 00000000 00000000 00001328 2**0
  61.                   CONTENTS, READONLY, DEBUGGING
  62.  29 .debug_line 00000082 00000000 00000000 000013bc 2**0
  63.                   CONTENTS, READONLY, DEBUGGING
  64.  30 .debug_str 00000133 00000000 00000000 0000143e 2**0
  65.                   CONTENTS, READONLY, DEBUGGING
  66.  31 .debug_loc 00000038 00000000 00000000 00001571 2**0
  67.                   CONTENTS, READONLY, DEBUGGING
rodata段如下:

点击(此处)折叠或打开

  1. Contents of section .rodata:
  2.  8048988 03000000 01000200 74686973 20697320 ........this is
  3.  8048998 72656164 206f6e6c 79206461 74610063 read only data.c
  4.  80489a8 6f6e7374 616e7420 64617461 00313233 onstant data.123
  5.  80489b8 34353600 78787878 00676c6f 62616c3a 456.xxxx.global:
  6.  80489c8 0009726f 64617461 3a000909 726f5f31 ..rodata:...ro_1
  7.  80489d8 203a2025 702c2573 0a000909 72775f32 : %p,%s....rw_2
  8.  80489e8 20706f69 6e74746f 3a202570 2c25730a pointto: %p,%s.
  9.  80489f8 00097277 64617461 3a000909 72775f31 ..rwdata:...rw_1
  10.  8048a08 203a2025 702c2573 0a000909 72775f32 : %p,%s....rw_2
  11.  8048a18 20646566 696e653a 2025700a 00096273 define: %p...bs
  12.  8048a28 733a0009 09627373 5f31203a 2025702c s:...bss_1 : %p,
  13.  8048a38 73697a65 3a25642c 25730a00 09096273 size:%d,%s....bs
  14.  8048a48 735f3220 3a202570 2c73697a 653a2564 s_2 : %p,size:%d
  15.  8048a58 2c25640a 00000000 09096273 735f3320 ,%d.......bss_3
  16.  8048a68 3a202570 2c73697a 653a2564 2c706f69 : %p,size:%d,poi
  17.  8048a78 6e742074 6f203a25 702c2573 0a000a6c nt to :%p,%s...l
  18.  8048a88 6f63616c 3a000973 7461636b 3a000909 ocal:..stack:...
  19.  8048a98 73746163 6b5f7368 6f72745f 313a2025 stack_short_1: %
  20.  8048aa8 702c2564 0a000909 73746163 6b5f6368 p,%d....stack_ch
  21.  8048ab8 61725f31 203a2025 702c2573 0a000909 ar_1 : %p,%s....
  22.  8048ac8 73746163 6b5f6368 61725f32 203a2025 stack_char_2 : %
  23.  8048ad8 702c2573 0a000000 09097374 61636b5f p,%s......stack_
  24.  8048ae8 63686172 7074725f 31206465 66696e65 charptr_1 define
  25.  8048af8 2061743a 2025700a 00000000 09097374 at: %p.......st
  26.  8048b08 61636b5f 63686172 7074725f 32206465 ack_charptr_2 de
  27.  8048b18 66696e65 2061743a 2025700a 00000000 fine at: %p.....
  28.  8048b28 09097374 61636b5f 636f6e73 74636861 ..stack_constcha
  29.  8048b38 725f3120 20203a20 25702c25 730a0000 r_1 : %p,%s...
  30.  8048b48 09097374 61636b5f 636f6e73 74696e74 ..stack_constint
  31.  8048b58 5f312020 20203a20 25702c25 640a0000 _1 : %p,%d...
  32.  8048b68 09097374 61636b5f 636f6e73 74696e74 ..stack_constint
  33.  8048b78 7074725f 31203a20 25702c25 702c2564 ptr_1 : %p,%p,%d
  34.  8048b88 0a000968 6561703a 00000000 09097374 ...heap:......st
  35.  8048b98 61636b5f 63686172 7074725f 3120706f ack_charptr_1 po
  36.  8048ba8 696e7474 6f3a2025 702c2573 0a000000 intto: %p,%s....
  37.  8048bb8 09097374 61636b5f 63686172 7074725f ..stack_charptr_
  38.  8048bc8 3220706f 696e7474 6f3a2025 702c2573 2 pointto: %p,%s
  39.  8048bd8 0a000909 72775f33 203a2025 702c2573 ....rw_3 : %p,%s
  40.  8048be8 0a000909 72775f34 203a2025 702c2564 ....rw_4 : %p,%d
  41.  8048bf8 0a000909 6273735f 343a2025 702c2573 ....bss_4: %p,%s
  42.  8048c08 0a00

data段如下:

点击(此处)折叠或打开

  1. Contents of section .data:
  2.  804a020 00000000 00000000 74686973 20697320 ........this is
  3.  804a030 676c6f62 616c2072 65616420 77726974 global read writ
  4.  804a040 65206461 74610000 a7890408 74686973 e data......this
  5.  804a050 20697320 6c6f6361 6c207265 61642077 is local read w
  6.  804a060 72697465 20646174 61000000 e7030000 rite data.......




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