为什么你想要在堆而不是堆栈上分配内存?

Mat*_*att 22 c memory heap stack memory-management

可能重复:
何时最好使用堆栈而不是堆,反之亦然?

我已经阅读了关于堆与堆栈的其他一些问题,但它们似乎更关注堆/堆栈的作用而不是使用它们的原因.

在我看来,堆栈分配几乎总是首选,因为它更快(只需移动堆栈指针与在堆中查找可用空间),并且您在使用它时不必手动释放已分配的内存.我可以看到使用堆分配的唯一原因是,如果要在函数中创建对象,然后在函数作用域之外使用它,因为堆栈分配的内存在从函数返回后自动取消分配.

还有其他原因使用堆分配而不是我不知道的堆栈分配吗?

caf*_*caf 37

有几个原因:

  • 主要的一点是,通过堆分配,您可以最灵活地控制对象的生命周期(从malloc/ callocfree);
  • 堆栈空间通常是比堆空间更有限的资源,至少在默认配置中是这样;
  • 可以优雅地处理分配堆空间的失败,而堆栈空间的耗尽通常是不可恢复的.

如果没有灵活的对象生命周期,那么有用的数据结构(如二叉树和链表)几乎不可能编写.


Kev*_*ose 19

  1. 您希望分配超出函数调用的范围
  2. 您希望节省堆栈空间(通常限制为几MB)
  3. 您正在使用可重新定位的内存(Win16,数据库等),或者想要从分配失败中恢复.
  4. 可变长度.你可以假装这个,但你的代码真的很讨厌.

最重要的是#1.一旦你进入任何类型的并发或IPC#1到处都是.即使是大多数非平凡的单线程应用程序,如果没有一些堆分配也很难设计.这实际上是伪造C/C++中的函数式语言.


Chr*_*utz 8

所以我想做一个字符串.我可以在堆上或堆栈上创建它.我们试试两个:

char *heap = malloc(14);
if(heap == NULL)
  {
    // bad things happened!
  }
strcat(heap, "Hello, world!");
Run Code Online (Sandbox Code Playgroud)

对于堆栈:

char stack[] = "Hello, world!";
Run Code Online (Sandbox Code Playgroud)

所以现在我在各自的位置都有这两个字符串.后来,我想让它们更长一些:

char *tmp = realloc(heap, 20);
if(tmp == NULL)
  {
    // bad things happened!
  }
heap = tmp;
memmove(heap + 13, heap + 7);
memcpy(heap + 7, "cruel ", 6);
Run Code Online (Sandbox Code Playgroud)

对于堆栈:

// umm... What?
Run Code Online (Sandbox Code Playgroud)

这只是一个好处,其他人已经提到了其他好处,但这是一个相当不错的好处.使用堆,我们至少可以尝试使分配的空间更大.随着堆栈,我们坚持我们拥有的东西.如果我们想要增长的空间,我们必须预先宣布它,我们都知道如何看到它:

char username[MAX_BUF_SIZE];
Run Code Online (Sandbox Code Playgroud)