以前看过C可执行文件的内存结构,但都只是当时很清楚,时候就忘的差不多了,没有细细去品味,一段时间就忘得差不多了,今天看了一些书籍和博文,决定将C可执行文件的内存结构的内容通过博客记录下来。

下面是一张C可执行文件的内存结构:

    wKiom1PKceKj7W0jAABPJEs8hUs207.jpg

    可见进程的逻辑地址空间可分为代码段,数据段,bss段,以及堆和栈段。这些段存放的数据分别是:

代码段:存放二进制程序,和常量。

可通过size命令查看可执行文件的各个段的大小:

#include <stdio.h>
int main(int argc,char *argv[])
{
        printf("hello world");
}
[root@bogon cstudy]# gcc 8.c 
[root@bogon cstudy]# size a.out 
   text       data        bss        dec        hex    filename
   1157        492         16       1665        681    a.out
#include <stdio.h>
int main(int argc,char *argv[])
{
        char *p="aaaa";//常量,应该放在text段
        printf("hello world");
}
[root@bogon cstudy]# gcc 8.c 
[root@bogon cstudy]# size a.out 
   text       data        bss        dec        hex    filename
   1162        492         16       1670        686    a.out

   可以发现text字段增加了5个字节,aaaa\0正好就是五个字节。

数据段:存放全局的或者静态的初始化变量

#include <stdio.h>
int main(int argc,char *argv[])
{
        printf("hello world");
}
[root@bogon cstudy]# gcc 8.c 
[root@bogon cstudy]# size a.out 
   text       data        bss        dec        hex    filename
   1157        492         16       1665        681    a.out
#include <stdio.h>
int a = 6;
int main(int argc,char *argv[])
{
        static int b = 6;
        printf("hello world");
}
[root@bogon cstudy]# size a.out 
   text       data        bss        dec        hex    filename
   1157        500         16       1673        689    a.out

可见data数据段增加了八个字节正好是两个int型变量。
但是如果变量未初始化,或者变量初始化为0是不放在数据段的,而是放在bss段。
#include <stdio.h>
int a = 0;
int main(int argc,char *argv[])
{
        static int b;
        printf("hello world");
}
[root@bogon cstudy]# gcc 8.c 
[root@bogon cstudy]# size a.out 
   text       data        bss        dec        hex    filename
   1157        492         24       1673        689    a.out

BSS段:存放未初始化的全局或者静态变量,或者初始化为0的全局或者静态变量。

堆段:一般是用户手动分配的,也就是通过malloc函数来手动分配内存的。

栈段:由编译器自动分配释放 ,存放函数的参数值,局部变量的值等