标签:
典型的C语言的内存分布由以下几块组成:
• Test segment (文本段)
• Initialzed data segment (初始化数据段)
• Uninitialized data segment (未初始化数据段)
• Stack (栈)
• Heap (堆)
(图a)
一:Text segment 文本段
文本段,通常也被称为是代码段(code segment),简称text,一般包含实际要执行的代码(机器指令)
作为内存中的一个区域,文本段通常被放置在堆和栈的下面,目的是防止堆或者栈溢出而导致文本段被修改(overwrite),也就是说,文本段是不可修改的。而且,它也是read-only,目的也是防止指令被修改。
通常情况下,文本段是可以共享的,因此同一时间多个实例之前共享同一份文本段。
二:Initialized Data Segment 初始化数据段
也通常被称为数据段,它是一个程序虚拟地址空间的一部分,通常包含了已经初始化好的全局变量和静态变量。
需要注意的是:数据段并非只读的,很明显,变量的值在程序运行过程中是可以被改变的。
C语言全局变量 const char* str = "hello";(data segment中)
静态变量 static int i=10;(data segment中)
三:Uninitialized data segment (未初始化数据段)
通常被称为bss(block started by symbol),在程序执行前这个段中的数据会被内核初始化为0(这似乎是以前的一种做法,不是很明白)
这个区域主要包含程序未初始化的全局变量,未初始化的静态变量。该段中的变量在执行之前初始化为0或NULL。
比如:静态声明 static int i; 和 全局变量 int j; 由于没有初始化都将在BBS段
四:栈
栈空间通常与堆空间紧邻,并且和堆空间的生长方向相反。如图a所示,stack由高地址区域向低地址区域生长,而heap区则相反,从低地址区域向高地址区域生长。当stack的指针到达了
heap指针所在的位置时,也就意味这可用内存已经被耗尽了。(当然,随着内存地址增加和虚拟内存技术的发展,它们可以被放置在几乎任何地方,但生长方向仍然相反)
stack包括了程序栈(LIFO),通常情况下在内存区域的高地址处。在x86的架构下,它向0地址处生长;在其他架构下它可能向其他方向生长。栈指针寄存器(stack pointer)记录栈顶地址,每次有值push进栈就会对栈指针进行修改。一个函数push进栈的一组值被称做堆栈帧(stack frame),堆栈帧保存有返回地址的最小的返回地址。
栈中存放有自动变量和每次函数调用时的信息。每次函数调用返回地址,一些调用者环境信息(比如寄存器)都被存放在栈中。然后新调用的函数就在栈中为他们的 自动或者临时变量分配内存空间,这就是C中递归函数调用的过程。每次递归函数调用自己,新的堆栈帧就被创建,这样新的变量集合就不会被其他函数实例的变量 集合影响了。
(可以参考http://blog.csdn.net/yang_yulei/article/details/45795591 ,写的很不错)
五:堆
heap是动态内存,由用户管理。通过malloc/alloc/realloc申请空间,通过free释放所申请的空间。
example:
#include <stdio.h> #include <stdlib.h> int a; static int b; void func( void ) { char c; static int d; } int main( void ) { int e; int *pi = ( int *) malloc ( sizeof ( int )); func (); func (); free (pi ); return (0); }
程序中声明的变量a、b、c、d、e、pi的存储类别和生命期如下所述:
• a是一个未初始化的全局变量,作用域为整个程序,生命期是整个程序运行期间,在内存的bbs段
• b是一个未初始化的静态全局变量,作用域为本源文件,生命期是整个程序运行期间,在内存的bbs段
• c是一个未初始化的局部变量,作用域为函数func体内,即仅在函数体内可见,生命期也是函数体内,在内存的栈中
• d是一个未初始化的静态局部变量,作用域为函数func体内,即仅在函数体内可见,生命期是整个程序运行期间,在内存的bbs段
• e是一个未初始化的局部变量,作用域为函数main体内,即仅在函数体内可见,生命期是main函数内,在内存的栈中
• pi是一个局部指针,指向堆中的一块内存块,该块的大小为sizeof(int),pi本身存储在内存的栈中,生命期是main函数内
• 新申请的内存块在堆中,生命期是malloc/free之间
参考:
标签:
原文地址:http://www.cnblogs.com/kakaxisir/p/4915364.html