C/C++内存布局
1. 内存分布图
1. Stack段:局部变量存放区域。
2. heap段:用户动态分配内存区域。
3. bss段:存放未初始化的全局或静态变量内存区域。(Block Started by Symbol)
4. 数据段:通常指存放已初始化的全局变量的内存区域。(data segment)
5. 代码段:通常指存放程序执行代码的一块内存区域。(code segment/text segment)
C规定,未初始化变量的初值为0,这个清0的操作是由启动代码完成的,还有已初始化变量的初值的设置,也是由启动代码完成的。
为了启动代码的简单化,编译链接器会把已初始化的变量放在同一个段:.data,这个段的映像(包含了各个变量的初值)保存在“只读数据段”,这样启动代码就可以简单地复制这个映像到 .data 段,所有的已初始化变量就都初始化了。
而未初始化变量也放在同一个段:.bss,启动代码简单地调用 memset 就可以把所有未初始化变量都清0。
2. 在C中分为5个存储区
1. 栈区:由编译器自动分配释放,存放函数的参数值,局部变量等。其操作方式类似数据结构中的栈。
2. 堆区:一般由程序员分配和释放(malloc,alloc,realloc,free),程序结束时内存空间由系统回收,与数据结构的堆毫无关系。
3. 全局/静态区:全局变量和静态变量的存储是在一块的。
初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。
4. 文字常量区:常量和字符串就是存放在这里,程序结束后由系统释放。
5. 程序代码区:存放函数体的二进制代码。
所有函数体外定义的变量就是全局变量,加了static修饰符后不管在哪里都存放在全局(静态区),全局的static变量只对该文件中有效,不能extern到别的文件用
在函数体内部定义的static表示在该函数体内有效。另外,函数体中的这样的字符串字面量存放在常量区。
int a = 0;//全局初始化区
char* p ;//全局未初始化区
void main()
{
int b;//局部变量
char s[] = "abc";//s在栈,abc在字符常量区
char *p2 ;//栈
char *p3 = "abcdef"//p3栈,abcdef在字符常量区
static int c = 0;//全局(静态)初始化区
p1 = (char*)malloc(10);//在堆上开辟10个字节的内存,p1本身在栈中
}
3. C/C++中堆区和自由存储区的区别与联系
1. malloc申请的内存在堆上,使用free释放。new申请的内存在自由存储区,用delete释放。
2. 堆(heap)是c语言和操作系统的术语。堆是操作系统所维护的一块特殊内存,它提供了动态分配的功能。
当程序运行时调用malloc()时就会从中分配,调用free可把内存释放。
自由存储区是C++中通过new和delete动态分配和释放对象的抽象概念,通过new来申请的内存区域可称为自由存储区。
基本上,所有的C++编译器默认用堆来实现自由存储区,即缺省的全局运算符new和delete会按照malloc和free的方式来实现,
这时由new运算符分配的对象,说它在堆上也对,说它在自由存储区也对。