下面是linux的各段分布,一般地址向上增长,但是从我们nm查看的各段,地址向下增长的;linux中各段在内存中分布如下:从底往上依次是,只读程序代码和数据段,堆,共享库的映射区域,用户栈;具体如下图:
程序实例:
注:(1)指针地址的大小永远为4;strlen()是根据'\0'计算的;字符数组一定会预留一个字节给'\0';
(2)常量区,无论是全局字符指针还是局部字符指针,都指向的字符串常量区(如果字符串相同的话),我们不能自己来释放,因此指向地址都相同;而一唯字符数组是存放在栈中的,地址不相同;
(3)凡是初始化为0的,不管它是static还是有const都存放在bss段;但是会有标志b或对应标志号来区别;
(4)用const来修饰的,但初值不为0的,一律放在只读区;
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define ARRAY_LENGTH (20)
char p1 = 'O'; //data
static char p2 = 'P'; //data static
char p3 ; //bss
static char p4 ; // bss static
static int z1; //bss
static int z2 = 5;
int x1; //bss
int x2 = 0; //bss
int x3 = 4; //data
const int r1 = 3; //read only data
const int r2;
static const int r3 = 3; //read only data static
static const int r4; //bss
//s1 is in stack,but 123456 is in heap but we can not free s, because "123456" is const ,system free;
char *s1 = "123456";
char *s2= "123456";
static char *s3= "123456";
char s4[] = "123456";//s is in stack, but 123456 is in stack
char s5[] = "123456";//s is in stack, but 123456 is in stack
static char s6[] = "123456";//s is in stack, but 123456 is in stack
char *s7;
static char *s8;
char *s9 = s4;
int add(int a, int b) //data
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
static int mul(int a, int b)//data static
{
return a * b;
}
int main(void)
{
char _p1 = 'O'; //stack
static char _p2 = 'P'; //data static
char _p3 ; //stack
static char _p4 ; // bss static
static int _z1; //bss
static int _z2 = 5; //data staic
int _x1;
int _x2 = 0;
int _x3 = 4;
const int _r1 = 3;
const int _r2;
static const int _r3 = 3; //read only data static
static const int _r4; //bss
//s1 is in stack,but 123456 is in heap but we can not free s, because "123456" is const ,system free;
char * _s1 = "123456";
char * _s2= "123456";
static char * _s3= "123456";
char _s4[] = "123456"; //s is in stack, but 123456 is in stack
char _s5[] = "123456"; //s is in stack, but 123456 is in stack
static char _s6[] = "123456"; //s is in stack, but 123456 is in stack
char * _s7;
static char * _s8;
char * _s9 = _s4;
printf("(exter address)s1:%x, s2:%x, s3:%x, s4:%x, s5:%x, s6:%x \n", s1, s2, s3, s4, s5, s6);
printf("(inter address)s1:%x, s2:%x, s3:%x, s4:%x, s5:%x, s6:%x \n", _s1, _s2, _s3, _s4, _s5, _s6);
char *s10 = (char *)malloc(5 * sizeof(char));
s10[0] = '1';
s10[1] = '1';
s10[2] = '\0';
printf("length of s3: %d\n", strlen(s10));
printf("size of s3: %d\n", sizeof(s10));
return 0;
}
上述程序对应的代码,使用nm -n test > 2.txt列出符号清单;其中B表示.bss段;D表示.data段非静态的;d表示.data段中静态的;T表示代码段中函数符号,非静态的;-R表示只读数据段;全局变量和静态变量(非 char)都在bss段;
nm -n test > 2.txt列出符号清单如下:
w _Jv_RegisterClasses
w __gmon_start__
U __libc_start_main@@GLIBC_2.0
U malloc@@GLIBC_2.0
U printf@@GLIBC_2.0
U strlen@@GLIBC_2.0
08048304 T _init
080483a0 T _start
080483d0 t __do_global_dtors_aux
08048430 t frame_dummy
08048454 T add
08048462 T sub
08048473 t mul
0804847f T main
080485e0 T __libc_csu_fini
080485f0 T __libc_csu_init
0804864a T __i686.get_pc_thunk.bx
08048650 t __do_global_ctors_aux
0804867c T _fini
08048698 R _fp_hw
0804869c R _IO_stdin_used
080486a0 R r1
080486a4 r r3
08048748 r _r3.2394
0804874c r __FRAME_END__
08049f0c d __CTOR_LIST__
08049f0c d __init_array_end
08049f0c d __init_array_start
08049f10 d __CTOR_END__
08049f14 d __DTOR_LIST__
08049f18 D __DTOR_END__
08049f1c d __JCR_END__
08049f1c d __JCR_LIST__
08049f20 d _DYNAMIC
08049ff4 d _GLOBAL_OFFSET_TABLE_
0804a014 D __data_start
0804a014 W data_start
0804a018 D __dso_handle
0804a01c D p1
0804a01d d p2
0804a020 d z2
0804a024 D x3
0804a028 D s1
0804a02c D s2
0804a030 d s3
0804a034 D s4
0804a03b D s5
0804a042 d s6
0804a04c D s9
0804a050 d _s3.2398
0804a054 d _s6.2401
0804a05c d _z2.2388
0804a060 d _p2.2384
0804a064 A __bss_start
0804a064 A _edata
0804a064 b completed.7021
0804a068 b dtor_idx.7023
0804a06c B x2
0804a070 b p4
0804a074 b z1
0804a078 b r4
0804a07c b s8
0804a080 b _s8.2403
0804a084 b _r4.2395
0804a088 b _z1.2387
0804a08c b _p4.2386
0804a090 B p3
0804a094 B x1
0804a098 B s7
0804a09c B r2
0804a0a0 A _end
w __gmon_start__
U __libc_start_main@@GLIBC_2.0
U malloc@@GLIBC_2.0
U printf@@GLIBC_2.0
U strlen@@GLIBC_2.0
08048304 T _init
080483a0 T _start
080483d0 t __do_global_dtors_aux
08048430 t frame_dummy
08048454 T add
08048462 T sub
08048473 t mul
0804847f T main
080485e0 T __libc_csu_fini
080485f0 T __libc_csu_init
0804864a T __i686.get_pc_thunk.bx
08048650 t __do_global_ctors_aux
0804867c T _fini
08048698 R _fp_hw
0804869c R _IO_stdin_used
080486a0 R r1
080486a4 r r3
08048748 r _r3.2394
0804874c r __FRAME_END__
08049f0c d __CTOR_LIST__
08049f0c d __init_array_end
08049f0c d __init_array_start
08049f10 d __CTOR_END__
08049f14 d __DTOR_LIST__
08049f18 D __DTOR_END__
08049f1c d __JCR_END__
08049f1c d __JCR_LIST__
08049f20 d _DYNAMIC
08049ff4 d _GLOBAL_OFFSET_TABLE_
0804a014 D __data_start
0804a014 W data_start
0804a018 D __dso_handle
0804a01c D p1
0804a01d d p2
0804a020 d z2
0804a024 D x3
0804a028 D s1
0804a02c D s2
0804a030 d s3
0804a034 D s4
0804a03b D s5
0804a042 d s6
0804a04c D s9
0804a050 d _s3.2398
0804a054 d _s6.2401
0804a05c d _z2.2388
0804a060 d _p2.2384
0804a064 A __bss_start
0804a064 A _edata
0804a064 b completed.7021
0804a068 b dtor_idx.7023
0804a06c B x2
0804a070 b p4
0804a074 b z1
0804a078 b r4
0804a07c b s8
0804a080 b _s8.2403
0804a084 b _r4.2395
0804a088 b _z1.2387
0804a08c b _p4.2386
0804a090 B p3
0804a094 B x1
0804a098 B s7
0804a09c B r2
0804a0a0 A _end