关于对堆栈的理解

**

在C/C++编程中,需要对内存有一定的了解,如何操作内存,管理内存,释放内存,内存中都存放着什么。**

栈区(stack):是由系统或者编译器进行分配和释放,存放局部变量的值、函数的参数值等,操作方式类似于数据结构中的栈。
堆区(heap):一般是由程序员自己进行分配内存空间和释放的,假设程序员没有对其进行释放,在程序结束时,有时候操作系统会对其进行系统回收,操作方式类似于链表。
全局区(静态区static):存放的是全局变量或者静态变量,并且是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和静态变量存放在相邻的一块区域内。在程序结束后由系统进行释放。
文字常量区:常量字符串所占的空间就是存放在这里的。程序结束后由系统进行释放。
程序代码区:一般是存放函数体的二进制代码。程序结束后由系统进行回收。
1、从申请方式来谈
栈:是由系统自动分配的,例如定义一个局部变量int b ;系统会自动在栈中为b开辟空间。
堆:需要程序员自己去申请内存空间,并且指明申请的大小,在C中用malloc函数,在C++中使用new来开辟新空间。
如:

p1 = (char*)malloc(10);
int *p2 = new int(20);

但注意p1和p2本身是在栈中的,分配的内存空间大小是在堆中的。
2、从申请后系统的响应来谈:
栈:只要栈的剩余空间大于申请所需要的空间,系统就会自动为程序分配内存,否则会报异常overflow栈溢出。
堆:对于堆,我们知道在操作系统中有一个记录空闲内存地址的链表,当系统收到程序申请内存时,会遍历该链表,寻找第一个空间大于所申请空间的堆节点,然后将该节点从链表中删除,并将该节点所占的空间分配给程序。对于大多数系统,会将这块内存的首地址处记录本次分配空间的大小,这样,我们在使用delete函数的时候,系统就会知道需要回收多少内存空间。如果分配给程序的内存空间大小和所申请的不一致,系统还会将多余的那部分进行回收,重新放入链表中。
3、从申请大小的限制来谈:
栈:在Windows环境下,栈的增长方向是由高地址指向低地址的,是一块连续的内存区域,意思就是栈顶的地址和站的最大容量是由系统预先设定好的,在Windows环境下,栈的大小是2MB,这是在系统编译阶段确定的。如果申请的空间找过栈空间,将会提示overflow,栈溢出异常。因此,能从栈获得空间大小是极小的。
堆:首先堆是由链表进行存储空闲的内存地址的,所以堆是不连续的内存区域。堆的增长方向是由低地址指向高地址的,并且堆的大小受限于计算机系统的虚拟内存。所以堆获得空间比较灵活,也比较大。
4、从申请效率来谈:
栈:首先栈是由系统进行分配的,并且空间大小固定,速度较快,但是对于程序员来说是不可控的。
堆:堆是由程序员自己申请并分配空间(C:malloc,C++:new),大小确定,相对于系统分配,比较可控,使用方便。但是速度比较慢,而且容易产生内存碎片,造成内存空间的浪费。
另外,在Windows环境下,最好的方式使用VirtualAlloc分配内存,不在栈,也不在堆,它是直接在进程的地址空间中保留一块内存。虽然用起来不方便,但是速度最快,也最灵活。

全局变量放在数据段;函数内部变量static int num放在数据段;函数内部变量char* p = “AAA”,p的位置在栈,指向的空间的位置在数据段;函数内部变量char *p = new char;p的位置在栈,指向空间的位置在堆;

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值