本文共 2599 字,大约阅读时间需要 8 分钟。
64位系统理论可寻址范围位2的64次方,但实际一般用不到,故linux的可寻址范围位2的48次方;其中128T为内核空间,128T为用户空间。编译器把源程序编译为各个段(Segment),段是由一个或多个节(section)组成。linux下可执行文件是ELF格式,因此可以通过以下命令查看各个段或节的内存地址:
readelf -S memoryCkeck #查看可执行程序由多少个节以及每个节的地址readelf -l memoryCheck #查看可执行程序头的地址以及大小,其中两个LOAD头是内存加载映射的重点size memoryCheck # 查看程序BSS,Data,Text各个段的大小cat /proc/${pid}/maps #同样可以查看程序的内存映射,其中没有名字的为匿名映射,一行为一个vm_area_struct
注:ELF格式的详细解析可以参考博文
平常理解的程序加载情况如图1所示,但实际操作系统加载时,操作系统不关心加载的内容,反而更加关心加载内容的权限。所以编译器会把权限相同的节会尽可能放在一起,故实际加载时的格局如如2所示:
图1
图2
注:图中的.xxx即节的名称,查看ELF文件时可以看到;
//memoryCheck.c#include#include #include /*查看进程中内存地址的分配*/int A; //全局变量未初始化int B = 0; //全局初始化为0的变量int C = 2; //全局初始化变量static int D; //全局静态未初始化变量static int E = 0; //全局静态初始化为0的变量static int F = 4; //全局静态初始化变量const int G = 5; //全局常亮const char H = 6;const char I = 7;int main(void){ int a; //局部未初始化变量 int b = 0; //局部初始化为0的变量 int c = 2; //局部初始化变量 static int d; //局部静态未初始化变量 static int e = 0; //局部静态初始化为0的变量 static int f = 4; //局部静初始化变量 const int g = 5; //局部常量 char char1[] = "abcde"; //局部字符串数组,保存在栈上 char *cptr = "123456"; //p在栈上,123456在常量区 int *heap = malloc(sizeof(int)*4); //堆 printf("PID is:%d\n\n",getpid()); printf("int A A_addr = %p\n",&A); printf("int B = 0 B_addr = %p\n",&B); printf("int C = 2 C_addr = %p\n",&C); printf("static int D D_addr = %p\n",&D); printf("static int E = 0 E_addr = %p\n",&E); printf("static int F = 4 F_addr = %p\n",&F); printf("const int G = 4 G_addr = %p\n",&G); printf("const char H = 6 H_addr = %p\n",&H); printf("const char I = 7 I_addr = %p\n",&I); printf("\n"); printf("int a a_addr = %p\n",&a); printf("int b = 0 b_addr = %p\n",&b); printf("int c = 2 c_addr = %p\n",&c); printf("static int d d_addr = %p\n",&d); printf("static int e = 0 e_addr = %p\n",&e); printf("static int f = 4 f_addr = %p\n",&f); printf("const int g = 5 g_addr = %p\n",&g); printf("\n"); printf("char char1[] = 'abcde'\t\t\tchar1_addr = %p\n",char1); printf("char char1[] = 'abcde'\t\t\t&char1_addr = %p\n",&char1); printf("char *cptr = '1'\t\t\tcptr_addr = %p\n",&cptr); printf("value of the cptr\t\t\tcptr_value = 0x%p\n",cptr); printf("value of %p\t\t\tvalue_0x%p = %d\n",cptr,cptr,*cptr); printf("int* heap = malloc(sizeof(int)*4)\theap__addr = %p\n",heap); printf("int* heap = malloc(sizeof(int)*4)\t&heap__addr = %p\n",&heap); pause(); /*程序结束运行后再回收堆内存,方便观察堆的地址*/ free(heap); return 0;}
转载地址:http://zoaxn.baihongyu.com/