Skip to content

堆和栈有什么区别?

约 1358 字大约 5 分钟

操作系统

2024-09-29

栈和堆之间的区别可能会让很多人感到困惑。因此,这里有一份有关栈和堆的问题和答案清单,我认为非常有帮助。

栈和堆存储在哪里?

它们都存储在计算机的 RAM 中。

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

在多线程应用程序中,每个线程都有自己的栈。但是,所有不同的线程将共享堆。由于多线程应用程序中的不同线程共享堆,这也意味着线程之间必须进行某种协调,以便它们不会同时尝试访问和操作堆中的同一块内存。

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

是的,对象可以存储在栈中。如果您在函数内部创建对象而不使用 new 运算符,那么这将在栈上创建并存储对象,而不是在堆上。假设我们有一个名为 Member 的 C++ 类,我们想为其创建一个对象。我们还有一个名为 somefunction() 的函数。代码如下所示:

main.cpp
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 的内存将被删除。

如果我们想在函数内部的堆上创建一个对象,那么代码将是这样的:

main.cpp
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 关键字创建的,这也意味着我们必须自己删除 m 对象——否则我们最终会遇到内存泄漏。

栈上的内存与堆上的内存相比能持续多长时间?

一旦函数调用运行完成,栈上专门为该函数调用创建的任何数据都将自动被删除。堆上的任何数据都将保留在那里,直到程序员手动删除。

栈的大小可以增长吗? 堆的大小可以增长吗?

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

如果当前堆的大小太小,无法容纳新的内存,那么操作系统可以向堆中添加更多内存。这是堆和栈之间的一个很大的区别。

栈和堆是如何实现的?

实现实际上取决于语言、编译器和运行时栈和堆的实现细节总是会有所不同,具体取决于所使用的语言和编译器。但从总体上看,一种语言中的栈和堆用于完成与另一种语言中的栈和堆相同的任务。

哪个更快——栈还是堆?为什么?

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

如何在栈和堆上释放内存?

当变量超出范围时,栈上的数据会自动释放。但是,在 C 和 C++ 等语言中,存储在堆上的数据必须由程序员使用内置关键字(如 freedeletedelete[ ])手动删除。Java 和 .NET 等其他语言使用垃圾收集自动从堆中删除内存,而无需程序员执行任何操作。

栈和堆可能出现什么问题?

如果栈内存不足,则称为栈溢出,并可能导致程序崩溃。堆可能存在碎片问题,当堆上的可用内存被存储为不连续(或断开)的块时会发生这种情况。因为已使用的内存块位于未使用的内存块之间。当出现过多碎片时,分配新内存可能是不可能的。因为即使有足够的内存用于所需的分配,但一个大块中可能没有足够的内存用于所需的内存量。

我应该使用哪一个——栈还是堆?

对于编程新手来说,使用栈可能是一个好主意,因为它更简单。 由于栈很小,因此当您确切知道数据需要多少内存,或者您知道数据的大小非常小时,您会想要使用它。当你知道数据需要大量内存,或者您只是不确定需要多少内存(例如动态数组)时,最好使用堆。




贡献者

更新日志

2025/3/3 08:52
查看所有更新日志
  • 3cbe5-improve(docs): use chinese punctuation
  • 42218-fix(docs): text typo
  • 1289a-improve(docs): delete extra whitespace and blank lines
  • c2111-modify(docs): remanage folders and rename files
  • 4f7fc-docs: update docs
  • 71726-升级主题+整理文章格式
  • 547bb-升级主题+新增文章+修改格式
  • fb196-升级版本+规整文档中的格式
  • d20bf-新增difference-between-stack-and-heap

Keep It Simple