操作系统: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.栈:栈内存只在程序运行时出现,在函数内部使用的变量、函数的参数以及返回值将使用栈空间,栈空间由编译器自动分配和释放。
测试实例:
-
#include <stdio.h>
-
#include <stdlib.h>
-
#include <string.h>
-
-
const char ro_1[ ] = {"this is read only data"}; //只读数据区(rodata)
-
-
static char rw_1[ ] ={"this is global read write data"};//已初始化读写数据段(data)
-
-
char bss_1[ 100]; //未初始化数据段(bss)
-
static int bss_2; //未初始化数据段(bss)
-
-
const char *rw_2 ="constant data"; //rw_2定义在已初始化读写数据段(data),字符串放在只读取数据段(rodata)
-
const char *bss_3; //未初始化数据段(bss)
-
-
-
-
int main()
-
-
{
-
short stack_short_1 = 9898; //定义在在栈(stack)上,占用2个字节
-
-
char stack_char_1[10]; //定义在在栈(stack)上开辟100个字节
-
-
char stack_char_2[ ]="abcdefg"; //s定义在在栈(stack)上,占用8个字节,“abcdefg”保存在s内存中
-
-
//定义在已初始化读写数据段(data),局部变量,只可在当前函数中使用
-
static char rw_3[ ]={"this is local read write data"};
-
-
static char bss_4[100]; //定义在未初始化数据段(bss),局部变量,只可在当前函数中使用
-
-
static int rw_4 = 999; //定义在已初始化读写数据段(data),局部变量,只可在当前函数中使用
-
-
const char stack_constchar_1[] = "hello world";//定义在在栈(stack)上,标识数组的数据不可更改
-
const int stack_constint_1 = 666;//定义在在栈(stack)上,标识整形数据不可更改
-
const int *stack_constintptr_1;//定义在在栈(stack)上,标识指针指向的整形数据不可更改
-
-
char *stack_charptr_1; //p1定义在在栈(stack)上,占用4个字节
-
-
char *stack_charptr_2="123456"; //p2定义在在栈(stack)上,
-
//p2指向的内容不能改,“123456”在只读数据区(rodata)
-
-
stack_charptr_1=(char *)malloc(10 * sizeof(char ) ); //分配内存区域在堆区(heap)
-
-
strcpy(stack_charptr_1,"xxxx"); //“XXXX”放在只读数据区(rodata),占5个字节
-
-
printf("global:\n");
-
printf(" rodata:\n");
-
printf(" ro_1 : %p,%s\n",ro_1,ro_1);
-
printf(" rw_2 pointto: %p,%s\n",rw_2,rw_2);
-
-
printf(" rwdata:\n");
-
printf(" rw_1 : %p,%s\n",rw_1,rw_1);
-
printf(" rw_2 define: %p\n",&rw_2);
-
-
printf(" bss:\n");
-
strcpy(bss_1,stack_char_2);
-
printf(" bss_1 : %p,size:%d,%s\n",bss_1,sizeof(bss_1),bss_1);
-
bss_2 = 7777;
-
printf(" bss_2 : %p,size:%d,%d\n",&bss_2,sizeof(bss_2),bss_2);
-
bss_3 = stack_constchar_1;
-
printf(" bss_3 : %p,size:%d,point to :%p,%s\n",&bss_3,sizeof(bss_3),bss_3,bss_3);
-
-
-
-
printf("\nlocal:\n");
-
printf(" stack:\n");
-
printf(" stack_short_1: %p,%d\n",&stack_short_1,stack_short_1);
-
strcpy(stack_char_1,"333222111");
-
printf(" stack_char_1 : %p,%s\n",stack_char_1,stack_char_1);
-
printf(" stack_char_2 : %p,%s\n",stack_char_2,stack_char_2);
-
printf(" stack_charptr_1 define at: %p\n",&stack_charptr_1);
-
printf(" stack_charptr_2 define at: %p\n",&stack_charptr_2);
-
-
printf(" stack_constchar_1 : %p,%s\n",stack_constchar_1,stack_constchar_1);
-
printf(" stack_constint_1 : %p,%d\n",&stack_constint_1,stack_constint_1);
-
stack_constintptr_1 = &stack_constint_1;
-
printf(" stack_constintptr_1 : %p,%p,%d\n",&stack_constintptr_1,stack_constintptr_1,*stack_constintptr_1);
-
-
printf(" heap:\n");
-
printf(" stack_charptr_1 pointto: %p,%s\n",stack_charptr_1,stack_charptr_1);
-
-
printf(" rodata:\n");
-
printf(" stack_charptr_2 pointto: %p,%s\n",stack_charptr_2,stack_charptr_2);
-
-
printf(" rwdata:\n");
-
printf(" rw_3 : %p,%s\n",rw_3,rw_3);
-
printf(" rw_4 : %p,%d\n",&rw_4,rw_4);
-
-
printf(" bss:\n");
-
printf(" bss_4: %p,%s\n",bss_4,bss_4);
-
-
free(stack_charptr_1); //使用free释放p1所指向的内存
-
-
return 0;
-
}
测试结果:
当前测试实例的各个段的大小以及分配情况:
-
t: file format elf32-i386
-
-
Sections:
-
Idx Name Size VMA LMA File off Algn
-
0 .interp 00000013 08048154 08048154 00000154 2**0
-
CONTENTS, ALLOC, LOAD, READONLY, DATA
-
1 .note.ABI-tag 00000020 08048168 08048168 00000168 2**2
-
CONTENTS, ALLOC, LOAD, READONLY, DATA
-
2 .note.gnu.build-id 00000024 08048188 08048188 00000188 2**2
-
CONTENTS, ALLOC, LOAD, READONLY, DATA
-
3 .gnu.hash 00000020 080481ac 080481ac 000001ac 2**2
-
CONTENTS, ALLOC, LOAD, READONLY, DATA
-
4 .dynsym 000000a0 080481cc 080481cc 000001cc 2**2
-
CONTENTS, ALLOC, LOAD, READONLY, DATA
-
5 .dynstr 0000007f 0804826c 0804826c 0000026c 2**0
-
CONTENTS, ALLOC, LOAD, READONLY, DATA
-
6 .gnu.version 00000014 080482ec 080482ec 000002ec 2**1
-
CONTENTS, ALLOC, LOAD, READONLY, DATA
-
7 .gnu.version_r 00000030 08048300 08048300 00000300 2**2
-
CONTENTS, ALLOC, LOAD, READONLY, DATA
-
8 .rel.dyn 00000008 08048330 08048330 00000330 2**2
-
CONTENTS, ALLOC, LOAD, READONLY, DATA
-
9 .rel.plt 00000040 08048338 08048338 00000338 2**2
-
CONTENTS, ALLOC, LOAD, READONLY, DATA
-
10 .init 0000002e 08048378 08048378 00000378 2**2
-
CONTENTS, ALLOC, LOAD, READONLY, CODE
-
11 .plt 00000090 080483b0 080483b0 000003b0 2**4
-
CONTENTS, ALLOC, LOAD, READONLY, CODE
-
12 .text 0000052c 08048440 08048440 00000440 2**4
-
CONTENTS, ALLOC, LOAD, READONLY, CODE
-
13 .fini 0000001a 0804896c 0804896c 0000096c 2**2
-
CONTENTS, ALLOC, LOAD, READONLY, CODE
-
14 .rodata 00000282 08048988 08048988 00000988 2**2
-
CONTENTS, ALLOC, LOAD, READONLY, DATA
-
15 .eh_frame_hdr 00000034 08048c0c 08048c0c 00000c0c 2**2
-
CONTENTS, ALLOC, LOAD, READONLY, DATA
-
16 .eh_frame 000000c4 08048c40 08048c40 00000c40 2**2
-
CONTENTS, ALLOC, LOAD, READONLY, DATA
-
17 .ctors 00000008 08049f14 08049f14 00000f14 2**2
-
CONTENTS, ALLOC, LOAD, DATA
-
18 .dtors 00000008 08049f1c 08049f1c 00000f1c 2**2
-
CONTENTS, ALLOC, LOAD, DATA
-
19 .jcr 00000004 08049f24 08049f24 00000f24 2**2
-
CONTENTS, ALLOC, LOAD, DATA
-
20 .dynamic 000000c8 08049f28 08049f28 00000f28 2**2
-
CONTENTS, ALLOC, LOAD, DATA
-
21 .got 00000004 08049ff0 08049ff0 00000ff0 2**2
-
CONTENTS, ALLOC, LOAD, DATA
-
22 .got.plt 0000002c 08049ff4 08049ff4 00000ff4 2**2
-
CONTENTS, ALLOC, LOAD, DATA
-
23 .data 00000050 0804a020 0804a020 00001020 2**2
-
CONTENTS, ALLOC, LOAD, DATA
-
24 .bss 00000128 0804a080 0804a080 00001070 2**5
-
ALLOC
-
25 .comment 0000002a 00000000 00000000 00001070 2**0
-
CONTENTS, READONLY
-
26 .debug_aranges 00000020 00000000 00000000 0000109a 2**0
-
CONTENTS, READONLY, DEBUGGING
-
27 .debug_info 0000026e 00000000 00000000 000010ba 2**0
-
CONTENTS, READONLY, DEBUGGING
-
28 .debug_abbrev 00000094 00000000 00000000 00001328 2**0
-
CONTENTS, READONLY, DEBUGGING
-
29 .debug_line 00000082 00000000 00000000 000013bc 2**0
-
CONTENTS, READONLY, DEBUGGING
-
30 .debug_str 00000133 00000000 00000000 0000143e 2**0
-
CONTENTS, READONLY, DEBUGGING
-
31 .debug_loc 00000038 00000000 00000000 00001571 2**0
-
CONTENTS, READONLY, DEBUGGING
rodata段如下:
-
Contents of section .rodata:
-
8048988 03000000 01000200 74686973 20697320 ........this is
-
8048998 72656164 206f6e6c 79206461 74610063 read only data.c
-
80489a8 6f6e7374 616e7420 64617461 00313233 onstant data.123
-
80489b8 34353600 78787878 00676c6f 62616c3a 456.xxxx.global:
-
80489c8 0009726f 64617461 3a000909 726f5f31 ..rodata:...ro_1
-
80489d8 203a2025 702c2573 0a000909 72775f32 : %p,%s....rw_2
-
80489e8 20706f69 6e74746f 3a202570 2c25730a pointto: %p,%s.
-
80489f8 00097277 64617461 3a000909 72775f31 ..rwdata:...rw_1
-
8048a08 203a2025 702c2573 0a000909 72775f32 : %p,%s....rw_2
-
8048a18 20646566 696e653a 2025700a 00096273 define: %p...bs
-
8048a28 733a0009 09627373 5f31203a 2025702c s:...bss_1 : %p,
-
8048a38 73697a65 3a25642c 25730a00 09096273 size:%d,%s....bs
-
8048a48 735f3220 3a202570 2c73697a 653a2564 s_2 : %p,size:%d
-
8048a58 2c25640a 00000000 09096273 735f3320 ,%d.......bss_3
-
8048a68 3a202570 2c73697a 653a2564 2c706f69 : %p,size:%d,poi
-
8048a78 6e742074 6f203a25 702c2573 0a000a6c nt to :%p,%s...l
-
8048a88 6f63616c 3a000973 7461636b 3a000909 ocal:..stack:...
-
8048a98 73746163 6b5f7368 6f72745f 313a2025 stack_short_1: %
-
8048aa8 702c2564 0a000909 73746163 6b5f6368 p,%d....stack_ch
-
8048ab8 61725f31 203a2025 702c2573 0a000909 ar_1 : %p,%s....
-
8048ac8 73746163 6b5f6368 61725f32 203a2025 stack_char_2 : %
-
8048ad8 702c2573 0a000000 09097374 61636b5f p,%s......stack_
-
8048ae8 63686172 7074725f 31206465 66696e65 charptr_1 define
-
8048af8 2061743a 2025700a 00000000 09097374 at: %p.......st
-
8048b08 61636b5f 63686172 7074725f 32206465 ack_charptr_2 de
-
8048b18 66696e65 2061743a 2025700a 00000000 fine at: %p.....
-
8048b28 09097374 61636b5f 636f6e73 74636861 ..stack_constcha
-
8048b38 725f3120 20203a20 25702c25 730a0000 r_1 : %p,%s...
-
8048b48 09097374 61636b5f 636f6e73 74696e74 ..stack_constint
-
8048b58 5f312020 20203a20 25702c25 640a0000 _1 : %p,%d...
-
8048b68 09097374 61636b5f 636f6e73 74696e74 ..stack_constint
-
8048b78 7074725f 31203a20 25702c25 702c2564 ptr_1 : %p,%p,%d
-
8048b88 0a000968 6561703a 00000000 09097374 ...heap:......st
-
8048b98 61636b5f 63686172 7074725f 3120706f ack_charptr_1 po
-
8048ba8 696e7474 6f3a2025 702c2573 0a000000 intto: %p,%s....
-
8048bb8 09097374 61636b5f 63686172 7074725f ..stack_charptr_
-
8048bc8 3220706f 696e7474 6f3a2025 702c2573 2 pointto: %p,%s
-
8048bd8 0a000909 72775f33 203a2025 702c2573 ....rw_3 : %p,%s
-
8048be8 0a000909 72775f34 203a2025 702c2564 ....rw_4 : %p,%d
-
8048bf8 0a000909 6273735f 343a2025 702c2573 ....bss_4: %p,%s
-
8048c08 0a00
data段如下:
-
Contents of section .data:
-
804a020 00000000 00000000 74686973 20697320 ........this is
-
804a030 676c6f62 616c2072 65616420 77726974 global read writ
-
804a040 65206461 74610000 a7890408 74686973 e data......this
-
804a050 20697320 6c6f6361 6c207265 61642077 is local read w
-
804a060 72697465 20646174 61000000 e7030000 rite data.......
阅读(1097) | 评论(0) | 转发(0) |