Why Stack And Heap

栈 和 堆 的原始由来

对于 栈 和 堆 ,我们通常也只是知道: 栈先进后出,堆无所谓。栈占内存比较小,堆比较大。栈占内存是连续的,堆不连续。 等这样一些区别,但它们的原始由来,我们清楚吗?

一开始我也是不清楚这点的,后来有次复习 C 教程,先看的内存管理,后看的堆栈,于是一下子开窍了(我不确定我的观点是否正确,仅作参考)。

假设这样的代码:

int main() {
  for(;;) {
    int a = 1;
  }
}

很明显,这样的代码是能够无限运行下去的。

但是,那句 int a = 1; 中的 1 肯定是有存在内存中的,那么如果这句代码无限循环运行,内存难道不应该被撑爆吗?

事实是它没有撑爆,所以,肯定有东西在帮我们回收内存。我们应该很容易就能猜到,就是编译器在帮我们做这个事情的。

所以,真实的代码其实相当于:

int main() {
  for(;;) {
    int a = 1;
    free(a);  // 不清楚该写成 free(a) 还是 free(&a), 总归就是这个意思吧
  }
}

既然回收内存是编译器帮我们做的,那对称一下,分配内存应该也是编译器帮我们做的:

int main() {
  for(;;) {
    int *a = malloc(sizeof(int));
    *a = 1;
    free(a);
  }
}

OK。。。编译器帮我们分配内存、回收内存,可是它是根据什么来帮我们做这些事情的呢?

作用域 。有的编程语言的作用域是函数作用域,有的是块作用域。但根据本身就是 作用域

于是, 栈就这么出现了

栈并非什么我们人类发明的概念,而是固有的。人们只是发现了栈而已。

OK, 说完了,那 呢?

其实没啥好说的,无非就是我们有手动管理内存的需求而已。无论是因为超大对象,如果放在栈里,导致常常复制删除,大量降低性能,还是有内存数据需要被跨函数访问到,这都需要我们手动管理内存。所以, 就出现了。

那根据上面的理论, 栈是编译器根据变量作用域帮我们自动管理内存的一种方式,堆是让程序员手动管理内存的方式 ,那么:

以上对于 栈 和 堆 的原始由来 的理解仅仅是个人看法,观点仅作参考。

[top]

comments powered byDisqus