前言:今天上课的时候跟yt说起了这个东西,之前只知道数据结构中的栈,了解学习一下堆。

堆在数据结构和内存中有着不同的意义。

在数据结构中,堆通常指完全二叉树,有父节点大于所有子节点的最大堆(反之也有最小堆)。应用有优先队列和堆排序。

在内存中,堆是指操作系统动态分配的内存。可以手动分配一段内存来使用,并在用后释放,借助malloc或new函数来实现。在C语言中,堆被称为“动态内存”,而在C++中,它被称为“自由存储区”。

虽然堆在数据结构和内存中有不同的意义,但都具有相似的特征,即可以根据需要动态调整大小。在数据结构中,堆经常使用数组来实现;在内存中,堆使用操作系统分配的虚拟地址空间来实现。

一、内存中的堆和栈

1、堆内存:

  1. 动态分配:堆内存用于存储动态分配的数据,即在运行时根据需要分配的内存,如使用malloc、calloc、realloc等函数分配的内存块。内存地址不连续
  2. 大小灵活:堆内存的分配和释放不受固定大小限制,可以根据需求动态改变
  3. 需手动释放:程序员需要手动管理堆内存,即在不再使用时显式地释放内存,通过free函数或者类似的方式进行释放。

一般而言,以下情况使用堆内存较为常见:

  • 需要动态分配内存的情况,比如不确定具体大小的数组、动态创建对象等。
  • 需要在函数之间共享数据,或者将数据保存到程序结束时才释放的情况。
  • 需要大量内存空间的情况,栈内存可能不足以满足需求。

2、栈内存:

  1. 自动分配:栈内存用于存储局部变量和函数调用时的临时数据,由编译器自动分配和释放。内存地址连续。
  2. 固定大小:栈内存的大小在编译时就已确定,并且大小是固定的。因此栈内存远大于堆。
  3. 自动释放:栈内存的分配和释放是自动进行的,当变量超出其作用域范围时,编译器会自动回收栈内存。

而以下情况使用栈内存较为常见:

  • 局部变量和临时数据的存储,如函数内部的变量。
  • 函数调用时的参数传递。
  • 对内存使用效率要求较高的场景,栈内存的分配和释放速度更快。

需要注意的是,堆和栈并非绝对的划分,实际使用中也存在栈上分配对象、堆上分配局部变量等特殊情况。因此,在编写程序时应根据具体需求和内存管理要求,合理选择使用堆内存或栈内存。

3、代码举例

#include <iostream>

void allocateOnHeap() {
int* ptr = new int(5); // 在堆上分配内存
std::cout << "Value on heap: " << *ptr << std::endl;
delete ptr; // 手动释放堆内存
}

void allocateOnStack() {
int value = 10; // 在栈上分配内存
std::cout << "Value on stack: " << value << std::endl;
} // 当函数执行完毕时,栈上的变量会自动释放

int main() {
allocateOnHeap(); // 调用函数,在堆上分配内存
allocateOnStack(); // 调用函数,在栈上分配内存

return 0;
}

运行结果:

Value on heap: 5

Value on stack: 10

二、数据结构中的堆和栈

  • 堆是一种基于树结构实现的数据结构,用于动态分配内存。堆中的数据没有特定的顺序,可以随时插入或删除元素,并且通常用于实现优先队列、堆排序等算法。
  • 栈是一种基于线性结构实现的数据结构,遵循”后进先出”(Last In First Out, LIFO)原则。主要用于临时存储和回收数据,例如函数调用时的参数传递、返回地址保存、局部变量存储等。

三、碎碎念

从openAI公司的大语言模型GPT3.5发布才不到一年,国产的 AI也全方位跟进了。最先的百度的文心一言,然后讯飞的星火助手,阿里的通义大模型,貌似目前只有腾讯比较落后一点?今天刚发现搜狗输入法也都支持ai了,不得不感叹发展真的好迅速啊,搜索引擎,办公软件,输入法,方方面面都越来越融入ai了。

而对于我自己而言,也越来越离不开ai了,包括这个博文的学习和代码生成,大大减少我学习的成本。插个眼,不知道一年后ai能发展成什么样呢?