当我们写完一个程序后,编译、链接、执行,表面看似很简单,其实程序执行过程中,内存为我们的程序做了很多事。
我们先来看一个图
一般我们将内存分为:堆区、栈区、全局区、代码区、常量区,各个区域存放的内容:
栈区:在程序中所创建的局部变量、参数、数组、指针等,当程序执行完后,将释放所占用的该块内存。
堆区:该片区域中存放着我们手工申请的内容,如:Malloc、new所创建。
全局区:全局变量、静态变量,在我们程序执行完之后将自动释放所占用的内存。
代码区:存放着函数体的二进制代码。
常量区:包含着整形常量、字符串常量,该区域内容不能被修改。
扫描二维码关注公众号,回复:
470721 查看本文章
- int GloVar = 0;//全局初始化区,存放在全局区
- int * GloVar2 ;//全局未初始化区,存放在全局区
- int main(void)
- {
- int lacVar;//局部变量,存放在栈中
- int lacVar = 0;//首先在常量区分配内存存放0,然后在栈中分配内存存放lacVar,最后将0赋值给lacVar。0 在程序结束后自动释放。
- int arr[10];//在栈中分配了一个数组,有连续的内存空间放int型数据,内存为(10*sizeof(int) )个字节
- char *point1;//在栈分配内存,指针是(sizeof(char) )个字节,此时没有向指针变量中赋值,也就是没有指向内存,此时操作这个指针会报错。
- char *point2= "000000";//首先常量区分配内存存放字符串常量,用指针point3,指向这块内存空间,只能访问。如果用 *point3 = "00";编译会报错,常量区不可修改.
- static int a1 = 0;//全局区(静态区)
- point1 = (char *)Malloc(4*sizeof(char)); //通过了Malloc 了在分配(4*sizeof(char))字节在堆中,当然指针在栈中。
- int *point3 = new int[10];//在堆中分配内存为( 10 * sizeof(int) )字节。
- return 0;
- }
从上述来看,他们所申请的内存方式是不一样的,栈是编译器自动管理,堆需要我们手工来创建,手工释放。在程序中,一般通过内存的指针来进行释放。
那他们在内存中还具有哪些差别呢?
一般在32位操作系统下,栈的内存一般都是一定的空间的大小的,在vc6下面默认的空间大小是1M,而堆的大小可以达到4G空间,从这个角度上讲堆内存几乎没有限制。 碎片问题
对于堆来讲,因为经常new/delete操作,造成内存空间不连续,造成大量的内存碎片,使程序效率低下。栈就没有这种问题。 生长方向
堆是向上生长,栈向下生长。意味在程序中申请栈和堆的内存时,内存地址变化方向不一样。栈中变量申请越往后,地址越小。 分配方式
堆是动态分配,没有静态分配的堆。栈有2中分配方式,静态分配就是常见的局部变量声明。动态分配有Malloc分配,系统自动回收。 分配效率
栈由机器系统提供的数据结构,计算机底层对栈支持:专门的寄存器存放栈的地址,有压栈出栈指令执行,决定栈的效率较高。堆是由c++函数库提供,机制比较复杂,如果没有足够内存空间(碎片过多),极有可能调用系统功能去增加程序数据段的内存空间,然后再返回。显然堆的效率比较低下。