问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

堆区与栈区

创作时间:
作者:
@小白创作中心

堆区与栈区

引用
CSDN
1.
https://blog.csdn.net/qq_50093188/article/details/145794707

在计算机编程中,堆区和栈区是内存中两个重要的存储区域。它们都是用来存储程序运行时的数据,但它们的使用方式和特点有所不同。本文将详细介绍堆区和栈区的概念、特点以及使用场景,并通过具体的代码示例帮助读者更好地理解它们的区别和适用场景。

一、栈区

栈区(Stack)是由系统自动分配和释放的内存空间,用于存储函数的参数值、局部变量的值等。栈区的数据结构是一种先进后出的数据结构,也就是说最后进栈的数据最先出栈,因此栈区具有自动管理和高效访问的特点。在函数调用时,会在栈区存储函数的参数值、返回地址以及函数的局部变量,函数执行完毕后,这些数据会被自动释放,不需要程序员手动管理。

#include <stdio.h>
#include <malloc.h>

int* fun51()
{
    int a;
    a = 10;
    return &a;
}
int main()
{
    /*栈区*/
    int* p;
    p = fun51();
    printf("%d\n",*p);
    printf("%d\n",*p);
    printf("%d\n",*p);
    
    return 0;
}

二、堆区

堆区(Heap)是由程序员分配和释放的内存空间,用于存储动态分配的数据。堆区的数据结构是一个没有固定大小的数据结构,程序员可以根据需要动态地分配和释放内存。在堆区中存储的数据可以在程序的任何地方被访问,但由于动态分配和释放内存需要程序员手动管理,因此容易出现内存泄漏或内存溢出等问题。

#include <stdio.h>
//#include <malloc.h>
#include<stdlib.h>
int* fun52()
{
    int* p=malloc(sizeof(int));//需要一段内存空间
    *p = 9;//存储一个整数
    return p;//分享 此 空间
}
int main()
{
    /*堆区*/
    int* q;
    q= fun52();
    printf("%d\n", *q);
    printf("%d\n", *q);
    printf("%d\n", *q);
    //手动释放 不需要的堆内存空间
    free(q);
    q = NULL;
    return 0;
}

三、比对栈区·堆区 使用

堆区使用malloc/calloc来申请空间

#include <stdio.h>
//#include <malloc.h>
#include<stdlib.h>
int main()
{
    //比对栈区·堆区 使用
    //存储意图:
    //栈区
    int aa = 4;
    int arr[] = {1,2,3,4};
    //堆区
    int* pa = malloc(sizeof(int));
    int* parr = malloc(sizeof(int)*4);
    //int* parr = calloc(4,sizeof(int));
    parr[0] = 1;
    parr[1] = 2;
    parr[2] = 3;//*(parr+1)
    parr[3] = 4;
    free(pa);
    free(parr);
    pa = NULL;
    parr = NULL;
    return 0;
}

四、malloc与calloc的区别

  • malloc:cd填充
  • calloc:0填充

五、realloc(扩充容量)

直接扩充:在原有的后面继续扩充空间。
异地扩充: 若申请空间太大可能会,把之前的数据一起搬家重新找空间扩建

#include <stdio.h>
//#include <malloc.h>
#include<stdlib.h>
int main()
{
    int* parr = malloc(sizeof(int)*4);
    parr[0] = 1;
    parr[1] = 2;
    parr[2] = 3;//*(parr+1)
    parr[3] = 4;
    //扩充容量
    parr=realloc(parr,sizeof(int)*8);
    parr[4] = 4;
    parr[5] = 4;
    parr[6] = 4;
    parr[7] = 4;
    free(pa);
    free(parr);
    pa = NULL;
    parr = NULL;
    return 0;
}

六、栈内存与堆内存的区别

  1. 分配方式与分配效率不同:当函数被调用执行时,其形参与函数体内的局部变量会一起在栈区内全部被创建出来,而堆内存的空间分配是 malloc、calloc 等函数被执行时才会分配空间。从分配效率上讲栈内存高于堆内存。
  2. 存储内容不同:堆内存更适用于存储数据量较大的情况,而栈内存更适合存储临时少量的数据。如果函数之间共享一个数据结构(比如链表),那么比较好的处理是把这个数据结构存储在堆内存,栈内存掌握这个堆空间的指针即可,这样就避免了栈空间频繁的创建与回收带来的开销。
  3. 管理方式不同:栈内存空间是由操作系统支持管理的,堆内存需要开发者自行维护——创建与回收。如果开发者疏忽了回收就会产生垃圾内存。所以堆内存是容易产生内存碎片的,栈内存由于系统自动维护则不会产生内存碎片。
  4. 生长方向与空间大小不同:栈与堆的内存空间都是动态延展的,但它们是相对方向的。栈的内存空间要小于堆的内存空间,所以堆内存空间更适合存储大一些的数据量。

总结

总的来说,栈区适合存储函数的参数值、局部变量等具有临时性和局部性的数据,而堆区适合存储动态分配的数据,如对象、数组等大小不固定或生命周期较长的数据。在编程过程中,程序员需要根据数据的特点和需求选择合适的存储区域,并合理地管理内存,以确保程序的安全性和高效性。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号