浅说内存分类:堆、栈

突然想起一直以来未能解释的一个c问题:

int n;

scanf("%d",&n);

char a[n];

即申请变成的数组,这个在编译阶段会出错。但用malloc、new之类分配内存则不会遇到这个问题。

一说是因为编译器会检测需要的堆栈空间的大小,如winodws默认的堆栈大小为1M,如需要的堆栈空间超出则会报错。变长数组使得这一检测没有结果,故而出错。而堆空间的使用在编译阶段则不做检查,故而没有问题。

Anyway,还不是很确定啦。

于是顺带复习了一下堆、栈等的关系,转载两篇文章吧。不过对于第二篇将内存分为五种的说法却是第一见,但其对堆、栈的区分讲的还是不错的,姑且一看吧。两篇文章较长,分开转载吧。

 PS:总有人说局部变量的内存是在编译阶段分配的……实在很汗……编译链接不过生成exe文件。这个时候程序只存在于硬盘里,何来的内存分配?!很容易给初学者误解的。如下的解释应该比较清晰些:

栈空间是静态分配的,编译期就决定了相对地址。由编译器管理的。给局部变量分配的栈内存,通过数据栈指针和相对偏移访问, 数据栈指针存放在EBP中,相对偏移值在编译期决定。编译时,对于局部变量(比如char   buf[10]),只不过生成了这样一条语句:

sub   esp,10;   //esp减去10,就在堆栈上腾出了10个字节的空间给变量buf(也可能为了对
                          //齐对多分配几个字节)。

等到程序执行到这里的时候才在栈上为其开辟一块空间。

函数结束回收时只要将esp的值恢复到之前的值就等于释放了这部分内存。

比如:
push   ebp
mov   ebp,esp   //原始esp保存起来
sub   esp,0xA

//....

mov   esp,ebp   //函数结束,恢复esp
pop   ebp           //恢复ebp

堆内存是动态分配,程序运行时才能确定分配的地址。

注意!栈空间是静态分配的并不代表栈里的局部变量是静态分配的!静态分配内存的方式并不是指编译的时候分配,而是指在程序加载到内存后在主函数main()调用之前分配!对于变量,也即应该只有static、全局变量的内存是静态分配的。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值