linux程序存储结构

    linux系统下,程序是一个可执行文件,通常是ELF格式。通常,linux的可执行文件拥有两种内存分配方式:存储时 和 运行时

1、存储时

    看实例,下面是对可执行文件aa运行size命令后得到的结果。

     [root@xxx1 algriom]# size aa
    text      data    bss    dec    hex   filename
    1257    500     16   1773    6ed  aa
    其中:
    text(代码区):表示正文段大小,是CPU执行的机器指令部分,通常,是可共享的,所以即使是频繁执行的程序在存储器中也只需有一个副本;
    data(初始化数据区):表示包含已经初始化(可执行文件包含了初始化的值)静态变量和全局变量的数据段大小;
    bss :表示未初始化的全局变量和未初始化的静态变量,称之为未初始化数据段

    PS:第4列和第5列是分别以十进制和十六进制表示的三个段的总长度。


2、运行时(进程结构)

运行时是指一个正在运行的进程在内存空间中的结构,也就是一个进程的结构。

一般包括代码区、全局存储区(初始化数据区DATA、未初始化数据区BBS)、文字常量区、堆和栈5个部分。

       (1)代码区:存放函数体的二进制代码

       (2)全局(静态)存储区:存放全局变量、静态变量;

                                     DATA:存放初始化的全局变量和静态变量static

                                     BBS:存放未初始化的全局变量和静态变量static,BBS段中,内存中所有字节默认值都是0;

                  【C中static作用】:1、隐藏;2、默认初始化为0,只能赋一次初值;3、保持局部变量内容持久

       (3)文字常量区(只读区):常量字符串;const修饰的全局变量保存在文本段中,const修饰的局部变量保存在栈中。

                                                      但是,数组只存放于栈、全局存储区

       (4)栈区:存储函数参数值、返回值、局部变量等。向下生长。

       (5)堆区:用于动态内存分配。向上生长。函数结束变量就消失。可以跨函数使用,直到free时才释放

    

int main()
{
	char a[] = "hello";
	char *p = "hello!";
	printf("_______%d\n",sizeof(a));
	printf("_______%d\n",sizeof(p));
	Test();

	system("pause");
	return 0;
}
          答案:6,4

          分析:p指针存储在栈,而其存储的hello!存在文字常量区;

                    a[] 数组存放在栈,此时的hello不仅仅存放在文字常量区,还拷贝一份存放在栈中,因为a是一个存放在栈上的数组。

       堆区和栈区的区别如下:


      (1)由操作系统自动管理,无需程序员手工控制,而区的申请和释放工作由程序员控制。一般由malloc(或new)函数来分配内存块,并且需要用free(delete)函数释放内存。如果程序员没有释放掉,那么就会出现常说的内存泄漏问题。需要注意的是,两个紧挨着定义的指针变量,所指向的malloc出来的两块内存并不一定的是紧挨着的,所以会产生内存碎片。


        是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。


      (2)是一块连续的内存区域,由系统预先设定,一般较小,从高地址向低地址增长;而是向高地址扩展的数据结构,是不连续的内存区域,空间较大。另外,分配的效率上,栈的分配比堆的分配要高效很多。


 注意:

    1 初始化的全局变量和静态变量保存在data中。

    2 未经初始化的全局变量和静态变量保存在BSS

    3 函数内部声明的局部变量保存在中。

    4 const修饰的全局变量保存在文本段中,const修饰的局部变量保存在栈中。

    5 字符串常量保存在文本段中。


3、例子程序

int a = 0; 全局初始化区

char *p1; 全局未初始化区

main()

{

int b; 栈

char s[] = "abc"; 栈

char *p2; 栈

char *p3 = "123456"; 123456在常量区,p3在栈上。

static int c =0; 全局(静态)初始化区

p1 = (char *)malloc(10);

p2 = (char *)malloc(20);

分配得来得10和20字节的区域就在堆区。

strcpy(p1, "123456"); 123456放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。

}

你可能感兴趣的:(堆栈,内存分配,文字常量区,代码区,全局变量区)