0%

【译】堆和栈的区别

因为经常有人问堆和栈的区别,就简单地知道栈向下增长;堆向上增长。在栈上创建的变量不需要自己释放;而在堆上创建的变量需要手动释放,否则会造成内存泄漏问题。

然后今天看到这篇文章详细写了堆和栈的区别,然后就简单翻译了一下,贴在下面了 :0

原文链接:https://www.programmerinterview.com/data-structures/difference-between-stack-and-heap/

堆和栈的区别

栈和堆之间的区别可能会让许多人感到困惑。所以,我们准备了一些关于栈和堆的问题,我们觉得这些问题会对理解它们之间的区别有帮助。

堆和栈存储在哪里?

它们都存在内存(RAM)中。

线程如何与堆栈交互?堆和栈如何在多线程中工作?

在多线程程序中,每个线程都有自己的 。但是,所有线程将共享一个
由于不同的线程共享堆,因此就存在多个线程同时访问一块内存的问题,所以就需要编程者来谨慎管理多线程的内存访问。

对象可以存储在栈上(而不是堆上)吗?

答案是肯定的,如果不使用 new 运算符在函数内创建对象,那么创建的对象就在栈上。
假设我们有一个名为 Member 的 C++ 类,我们要为其创建一个对象。
比如在 somefunction() 函数中我们需要这个对象。

在栈上创建对象的代码

1
2
3
4
5
6
7
8
9
10
void somefunction() {
/* create an object "m" of class Member
this will be put on the stack since the
"new" keyword is not used, and we are
creating the object inside a function
*/

Member m;

} //the object "m" is destroyed once the function ends

一旦函数运行结束,对象 m 就会被销毁掉,m 对应在栈上的内存也会被回收。

在堆上创建对象的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void somefunction() {
/* create an object "m" of class Member
this will be put on the heap since the
"new" keyword is used, and we are
creating the object inside a function
*/

Member* m = new Member( ) ;

/* the object "m" must be deleted
otherwise a memory leak occurs
*/

delete m;
}

在上面的代码中,m 是使用 new 创建的。这意味着将在堆上创建 m 。由于 m 是使用 new 创建的,必须手动 delete m 对象,否则将导致内存泄漏问题。

堆栈的大小能增长吗?

栈被设置为固定大小,不能超过它的固定大小(尽管有些语言有允许这样做的扩展)。因此,如果栈上没有足够的空间来处理分配给它的内存,就会发生栈溢出(stack overflow)。栈溢出通常发生在调用许多嵌套函数或者无限递归调用时。

如果当前堆的大小太小而无法提供新内存时,操作系统可以向堆中添加更多内存(If the current size of the heap is too small to accommodate new memory, then more memory can be added to the heap by the operating system.)。这是堆和栈之间的最大区别之一。

堆栈是如何实现的?

它们的实现取决于语言、编译器和运行时,堆栈实现的小细节总是不同的,这取决于所使用的语言和编译器。但是,从大局来看,不同语言中的堆栈都是用来完成相同的事情。

堆栈哪个更快?

栈比堆快得多。
这是因为在栈上分配内存就像向上移动栈指针一样简单。

堆栈上的内存如何 deallocated

当变量超出作用域时,栈上的数据将自动 deallocated。 但是,在 C 和 C ++ 等语言中,程序员必须使用 free,delete 或 delete [] 之类的内置关键字手动删除存储在堆上的数据。 Java 和 .NET 等其他语言使用垃圾收集来自动从堆中删除内存,而程序员不必做任何事情。

堆栈会出什么问题?

如果栈内存不足,会导致栈溢出问题,并可能导致程序崩掉。
堆可能存在碎片问题,当堆上的可用内存不连续(或断开连接)时会出现碎片问题,因为已使用的内存块位于未使用的内存块之间。当碎片问题很严重时,分配新内存可能会失败,因为即使有足够的内存用于所需的分配,但是这些内存并不是连续的。

我应该使用栈还是堆?

对于刚开始编程的人来说,使用栈可能更好,因为它比堆更简单。
因为栈很小,所以当确切知道需要多少内存时,或者数据非常小时,可以使用栈。当需要大量内存,或者不确定需要多少内存(例如使用动态数组)时,最好使用堆。

Welcome to my other publishing channels