C++堆(Heap)和栈(Stack)的区别

参考网址:https://www.cnblogs.com/ChenZhongzhou/p/5685537.html

参考网址:http://www.cnblogs.com/SinSay/archive/2008/11/12/1332076.html

重点强调的是

  • 数据结构中的栈和堆

1. 对于数据结构中的栈:连续存储的数据结构,先进后出,通常用入栈、出栈等操作,若想要读取其中的一个元素,就需要把之前的元素全部取出来出栈才可以完成。类比与现实中的箱子。

2. 对于堆:非连续存储结构,每个节点有一个值,整个树是经过排列的。特点是根节点的值最大(或最小),且根节点的两个子树也是一个堆。常用来实现优先队列,存取随意。

  • 内存中的栈和堆

一般来说内存,指的都是计算机的随机存储器(RAM),程序都在此运行。大致分类:


栈内存:程序自动分配和释放,回收,速度快,使用方便,程序员无法控制(且每次分配的位置可能不同)。若分配失败,则提示栈溢出。注意:const局部变量也存储在栈区。栈区向地址减小的方向增长。

//测试栈内存
#include <iostream>
int main()
{
    int i = 10; //变量i储存在栈区中
    const int i2 = 20; //局部的静态变量
    int i3 = 30;
    std::cout << &i << " " << &i2 << " " << &i3 << std::endl;
    return 0;
}

测试结果为:&i<&i2<&i3,证明地址是递减的


堆内存:程序员向操作系统申请一块内存,当系统收到程序申请时,会遍历一个记录空闲内存的链表,寻找第一个大于所申请空间的堆节点,然后将该节点从空闲的节点中删除,并将该节点分配给程序。分配的速度很慢,分配的不连续,容易碎片化。此外程序员申请,也必须由程序员进行销毁,否则的话会出现内存的泄露

//测试堆内存和栈内存的区别
#include <iostream>
int main()
{
	int i = 10; //变量i储存在栈区中
	char pc[] = "hello!"; //储存在栈区
	const double cd = 99.2; //储存在栈区
	static long si = 99; //si储存在可读写区,专门用来储存全局变量和静态变量的内存
	int* pi = new int(100); //指针pi指向的内存是在 堆区,专门储存程序运行时分配的内存

	int* pi2 = new int[5];//定义一个动态数组,开辟堆空间
	for(int j=0;j<5;j++)  //完成初始化
		pi2[j] =j;

	
	std::cout<<"*********栈(stacks)和堆(heap)**************"<<std::endl;
	std::cout <<"栈内存地址递减:"<< &i << " " << &pc << " "<< &cd<<std::endl;

	std::cout <<"可读写区存储全局变量和静态变量:"<< &si << std::endl;

	std::cout<<"*********栈(堆(heap)**************"<<std::endl;
	std::cout <<"单个堆变量:"<< &pi << std::endl;
	for(int j=0;j<5;j++)
     std::cout <<"一维堆变量:"<<j+1<<"值为:"<< pi2[j] <<"地址为:"<<&(pi2[j])<< std::endl;
		
	delete pi; //需程序员自己释放
	delete []pi2;
	return 0;
}
测试结果:

运行多次发现:pi所指向的地址不连续,是跳跃的,一维堆变量整体跳跃,可理解成一个小的整体(地址与栈相反,栈是地址减小,而堆里面是地址增大);而&si是一致的,存储在可读写区;前三个变量都在栈内,程序自动分配和销毁,而储存在堆里面的则需要程序员自己进行销毁。

关于堆和栈的比喻

堆和栈的区别可以引用一位前辈的比喻来看出:

使用栈就象我们去饭馆里吃饭,只管点菜(发出申请)、付钱、和吃(使用),吃饱了就走,不必理会切菜、洗菜等准备工作和洗碗、刷锅等扫尾工作,他的好处是快捷,但是自由度小。

使用堆就象是自己动手做喜欢吃的菜肴,比较麻烦,但是比较符合自己的口味,而且自由度大。




猜你喜欢

转载自blog.csdn.net/haoaoweitt/article/details/80890178