堆和栈的区别-,堆和栈的理解

  堆和栈的区别?,堆和栈的理解

  以下内容转自http://blog..net/hairetz/article/details/4141043.

  一,程序的初步知识记忆分配

  C/C编译程序占用的内存分为以下几部分

  1.stack)——由编译器自动分配和释放,它存储函数的参数值、局部变量的值等。那

  该操作类似于数据结构中的堆栈。

  2.heap)——一般由程序员分配和释放。如果程序员不释放它,操作系统可能会在程序结束时返回它。

  收到。注意在数据结构上和堆不同,但是分配方式和链表差不多,呵呵。

  3.全局区域(静态区域)-全局变量和静态变量存储在一起并被初始化。

  全局变量和静态变量在一个区域,未初始化的全局变量和未初始化的静态变量在相邻的区域。

  一个区域。-程序完成后由系统释放。

  4.文本常量区域-常量字符串位于此处。程序完成后,由系统释放。

  5.程序代码区——存储函数体的二进制代码。

  第二,示例程序

  这是一位前辈写的,写的很详细。

  //main.cpp

  int a=0;全局初始化区

  char * p1全局未初始化区域

  主()

  {

  int b;棚

  char s[]= ABC ;棚

  char * p2棚

  char * p3= 12345623456/0在常量区,p3在堆栈上。

  静态int c=0;全局(静态)初始化区

  P1=(char *)malloc(10);

  p2=(char *)malloc(20);

  10和20字节的分配区域在堆区域。

  strcpy(p1, 123456 );23456/0放在常量区,编译器可能会将其与p3指向的‘123456’进行比较。

  优化到一个地方。

  }

  二、堆和栈的理论知识

  2.1应用方法

  堆栈:

  由系统自动分配。比如在函数中声明一个局部变量int b;系统自动在栈中为B打开一个空的空间

  间距

  堆:

  需要程序员自己申请,并在c中注明malloc函数的大小。

  P1=(char *)马洛克(10);

  在c中使用new运算符。

  P2=新字符[10];

  但是请注意,p1和p2本身就在堆栈中。

  2.2

  应用后系统的响应

  堆栈:只要堆栈剩余空间大于请求空间,系统就会为程序提供内存,否则会报告异常提示堆栈溢出。

  出去。

  Heap:首先你要知道操作系统有一个空闲内存地址的链表。当系统接收到程序的应用时,

  遍历链表,查找其空间大于应用空间的第一个堆节点,然后从空闲节点列表中列出该节点。

  删除,并将该节点的空间分配给程序。此外,对于大多数系统,它将在这个内存空间中

  在第一个地址记录这个分配的大小,以便代码中的delete语句可以正确地释放这个内存空间。

  此外,因为找到的堆节点的大小不一定完全等于应用程序的大小,所以系统会自动发送冗余的那个。

  把它放回自由链表。

  2.3应用规模的限制

  堆栈:在Windows下,堆栈是一种扩展到低位地址的数据结构,是连续内存的一个区域。这句话的意思

  但是堆栈顶部的地址和堆栈的最大容量是由系统预先指定的。在WINDOWS下,堆栈的大小是2M(也有

  说是1M,简而言之就是编译时确定的常数)。如果应用的空间超过堆栈的剩余空间,它将

  提示溢出。因此,堆栈中的可用空间很小。

  Heap: Heap是扩展到高位地址的数据结构,是一个不连续的内存区域。这是因为系统使用链表来存储。

  空闲内存地址自然是不连续的,链表的遍历方向是从低位地址到高位地址。堆的大小

  受到计算机系统中可用虚拟内存的限制。可见堆获得的空间更灵活,更大。

  2.4应用效率比较:

  堆栈由系统自动分配,速度更快。但是程序员控制不了。

  Heap是new分配的内存,一般比较慢,容易出现内存碎片,但是用起来最方便。

  另外,在WINDOWS下,最好的方法是使用VirtualAlloc来分配内存。他不在堆里,也不在栈里。

  在直接进程的地址空间里保留一块内存,虽然用起来最不方便。但它速度快,最灵活。

  2.5堆和堆栈中的存储内容

  栈:当一个函数被调用时,栈上的第一条是主函数中的下一条指令(函数调用语句中的下一条指令可以

  执行语句的地址),然后是函数的参数。在大多数C编译器中,参数是从右向左堆叠的。

  然后是函数中的局部变量。请注意,静态变量是不堆叠的。

  当这个函数调用完成后,先将局部变量弹出堆栈,然后是参数,最后堆栈顶部的指针指向它们开始时存储的位置。

  地址,即主函数中的下一条指令,程序从这里继续运行。

  堆:通常,在堆的头部使用一个字节来存储堆的大小。堆的具体内容由程序员安排。

  2.6访问效率比较

  char S1[]= aaaaaaaaaaaaaaaa ;

  char * s2= bbbbbbbbbbbbbbbbb

  aaaaaaaaaa是在运行时分配的;

  Bbbbbbbbbbb是在编译时确定的;

  但是在以后的访问中,栈上的数组比指针指向的字符串(比如heap)要快。

  例如:

  #包括

  void main()

  {

  char a=1;

  char c[]= 1234567890 ;

  char * p= 1234567890

  a=c[1];

  a=p[1];

  返回;

  }

  相应的装配代码

  10:a=c[1];

  00401067 8A 4D F1 mov cl,字节指针[ebp-0Fh]

  0040106A 88 4D FC mov字节ptr [ebp-4],cl

  11:a=p[1];

  0040106D 8B 55 EC mov edx,dword ptr [ebp-14h]

  00401070 8A 42 01 mov al,字节ptr [edx 1]

  00401073 88 45 FC mov字节ptr [ebp-4],al

  第一个将字符串中的元素直接读入寄存器cl,而第二个首先读取指针值。

  在edx中,根据edx读取字符明显很慢。

  2.7总结:

  堆和栈的区别可以通过下面的比喻看出:

  使用栈就像在餐厅吃饭一样,只需要点餐(发出申请)、付款、吃饭(使用)。当你吃饱了,就

  去,不讲究切菜、洗菜等准备工作和洗碗、刷锅等收尾工作,他的优点是快,但既然

  通过小的程度。

  就像自己做自己喜欢的菜一样。很麻烦,但是很适合自己的口味,而且很自由。

  度。(经典!)

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: