引言
现在的应用程序都运行在一个虚拟内存空间里,以32位系统为例,其寻址空间为4G。
大部分的操作系统为4G内存空间,一般分为两个部分:
- 内核态空间(应用程序无法直接访问),Linux默认将高地址的1G空间分配给内核态空间,
- 用户态空间(用户使用),剩下的低地址的3G内存空间为用户态空间。
C/C++程序内存空间分布(用户态空间)
- 栈区(stack):由编译器自动分配与释放,存放函数参数、局部变量、返回数据、返回地址等。其操作类似于数据结构中的栈。
- 堆区(heap):由程序员手动分配与释放,若程序结束时未释放,可能由OS(Operating System)回收。其分配类似于链表。
- 全局区/静态区(static):存放全局变量、静态变量和常量。程序分配时由系统分配,程序结束后由系统释放。全局区分为已初始化全局区(data)和未初始化全局区(bss)。
- 常量区(文字常量):存放常量字符串,由系统分配与释放。
- 代码区:存放函数体的二进制代码(类成员函数和全局区)。
栈(stack)与堆(heap)的区别:(6个方面)
-
管理方式不同。 **堆:**由程序员申请与释放,容易产生memory leak. **栈:**是由编译器自动管理,无需程序员手动控制; -
**空间大小不同。**一般在32位系统下, **堆内存:**几乎没有限制的,最大可以到4G。 **栈内存:**一般有空间大小限制,例如,在VS下,默认的栈空间大小是1M。 -
**分配方式不同。**内存有2种分配方式:静态分配和动态分配。 **堆:**全部都是动态分配内存,没有静态分配的堆,由malloc, calloc函数进行分配。 **栈:**多数都是静态分配内存,由编译器完成,如分配局部变量。但是栈的动态分配和堆不同,由编译器动态分配与释放,无需程序员手动实现。 -
生长方向不同。 **堆:**向上生长(内存地址增加); **栈:**向下生长(内存地址减小)。 -
是否产生碎片。 **堆:**频繁的(malloc/free)(new/delete)会造成内存空间的不连续,从而产生大量碎片,降低程序效率。 **栈:**栈是先进后出,一个内存块从栈中间弹出之前,在它上面的后进的栈内容已经被弹出,故不会产生碎片问题。 -
分配效率不同: **堆:**由库函数提供(malloc/free)(new/delete),机制复杂,速度较慢。 栈:是系统提供的数据结构,由系统自动分配,速度较快。
转自(原文链接):https://blog.csdn.net/cherrydreamsover/article/details/81627855
区分概念与使用:(简单了解即可)
全局变量与静态全局变量:
- 都属于常量区。
- **全局变量:**在别的文件中可以调用;**静态全局变量:**只在本文件中有效,别的文件无法调用该变量。
- 若在另一文件中定义一个同名全局变量,会出错。
局部变量与静态局部变量:
- **函数内部局部变量:**属于栈区;**静态局部变量:**属于常量区的。
- **局部变量:**会随该函数的结束而结束;**静态局部变量:**不会随函数的结束而销毁,而是随整个程序结束而结束,但别的函数无法调用该变量,;
- 若这两个变量未给初值,会被自动定义。**局部变量:**随机值;**静态局部变量:**0。
- **局部变量:**在调用期间,每调用一次,赋一次值。**静态局部变量:**只在编译期间赋值一次,以后函数每次调用,不再赋值。
转自(原文链接):https://blog.csdn.net/cherrydreamsover/article/details/81627855
|