c语言基础(五)之内存、堆栈区-阿里云开发者社区

开发者社区> 开发与运维> 正文
登录阅读全文

c语言基础(五)之内存、堆栈区

简介:

 

 

指针运算:

指针的运算在数组的运算中才有意义。其它指针操作的运算都无意义。

 

只要是指针类型,它在内存中所占的长度都是4个byte。(前提是32位系统)

 

传统数组被创建出来,它是被创建在栈空间上的。也就是说程序员没有办法

去清空栈空间上的内容。

 

动态内存分配:

使用malloc函数,能够动态分配内存。注意要引入#include<malloc.h>函数头文件

malloc(a);a表示int类型参数。就是要申请多少个byte长度的内存。

       返回值 :是申请县的空间的首地址(void类型)。它是一个指针类型的返回值。

                      要作相应的强制类型转换。

释放空间free(p);//p首地址

记住:在free后尽量不要在使用该变量。

       避免错误方法:在释放free(p)后,p=NULL(大写);若其它地方有使用p,则会有错误提示。

 

用动态分配内存,可以在主函数中使用子函数的变量的值。

 

例子:

int len=0;

scanf("%d",&len);

int* p = (int*)malloc(sizeof(int)*len)//若len=6,执行完毕后,申请了多少byte内存?

 //1.静态申请的内存 int* 4byte

 //2.动态内存4*6=24byte

 //所以,总共申请了 24+4 = 28byte内存

 

realloc(p,q);//p表示:重新分配哪一块内存空间,q表示:重新分配的大小

           返回值:是内存空间的首地址。

 

静态内存和动态内存:

静态内存是程序编译执行后系统自动分配的,由系统自动释放。静态内存

                 是栈分配的。动态内存是堆分配的。

 

静态内存和动态内存区别:

1.从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在

    程序的整个运行期间都存在。例如:全局变量,static变量

2.在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,

    函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的

    指令集中,效率很高,但是分配的内存容量有限。

3.从堆上分配,亦称动态内存分配。程序在运行的时候用mallo(c)c或new(java)申请任意

   多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存

   期由我们决定,使用非常灵活,但问题也最多。

 

堆和栈的区别:

1.申请方式:

栈:由系统自动分配,例如,声明一个局部变量int b;系统自动在栈中为b开辟空间,

        栈空间是后进先出,由系统释放空间。

堆:需要程序员自己申请,并指明大小,在c中用malloc函数

        如:p1=(char*)malloc(10);

              但是注意p1本身是在栈中的。

2.申请后系统的响应

栈:只要栈剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。

堆:首先应该知道操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,

       会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点

       链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存

       空间中的首地址处记录本次分配的大小,这样,代码中的delete语句才能正确的释放

       本内存空间。另外,由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动

       的将多余的那部分重新放入空闲链表中。

3.申请大小的限制

栈:在windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的

        意思是栈顶的地址和栈的最大容量是系统预先规定好的,在windows下,栈的大小是

        2M(vc编译选项中可以设置,其实就是一个stack参数,缺省值2M),如果申请的空间

        超过酷我剩余空间时,将提示overflow。因此,能从栈获得的空间比较小。

堆:是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲

        内存地址的,自然是不连续的。而链表的遍历方向是由低向高地址。堆的大小受限于计算机

        系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。

4.申请效率的比较:

栈:由系统自动分配,速度较快,但是程序员无法控制的。

堆:由malloc/new分配的内存,一般速度 比较慢,而且容易产生内存碎片,不过用起来方便。

5堆和栈的存储内容:

栈:在函数调用时,第一个进栈的是主函数中后的下一条指令(函数调用语句的下一条可执行

       语句 )的地址,然后是函数的各个参数,在大多数的c编译器中,参数是由右往左入栈的,

      然后是函数中的局部变量。注意:静态变量是不入栈的。

堆:一般是在堆的头部用一个字节存放堆的大小。堆中的具体内容有程序员安排。

6.内存的回收

栈:栈上的分配的内存,编译器会自动回收。

堆:堆上分配的内存,要通过free来显示的收回,否则会造成内存泄漏。

 

                               

 

 

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章
最新文章
相关文章