C 堆栈和堆的大小

C 堆栈和堆的大小,c,memory,stack,size,heap-memory,C,Memory,Stack,Size,Heap Memory,我读到windows中c中的堆栈大小默认为1MB,linux中为8MB。 但这种规模是可以改变的 1-当我担心大小限制时,为什么要使用堆,因为我可以更改堆栈以适应所有数据 2-更改堆栈限制并使其变大有哪些缺点 ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­

我读到windows中c中的堆栈大小默认为1MB,linux中为8MB。 但这种规模是可以改变的

1-当我担心大小限制时,为什么要使用堆,因为我可以更改堆栈以适应所有数据

2-更改堆栈限制并使其变大有哪些缺点

­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ ­­­­­­­­­­­­­­­­­­ 注:此答案有待编辑和修改扩展了更多dis/优点

使用堆栈的缺点:

  • 堆栈上的对象仅在创建块处于活动状态时才有效。您可以将引用移交给被调用的方法/函数,但不能将引用返回给调用方
  • 堆栈的空间在程序AFAIK开始时完全分配。它会减少其他程序的可用内存。堆是动态分配的,可以根据需要增长
  • 除非您的编译器知道如何进行编译,并且您使用适当的选项进行编译,否则您的程序将不会检测到内存溢出,这可能是由编程错误或错误的假设引起的
使用堆栈的优点:

  • 编写更少的代码
  • 当堆栈上的对象退出其生命周期时自动释放分配的空间
1-当我担心大小限制时,为什么要使用堆,因为我可以更改堆栈以适应所有数据

这不是尺寸的问题,而是寿命的问题。具有
auto
存储持续时间的对象(即在大多数实现中从堆栈中分配的对象)仅在其封闭范围或函数的生命周期内存在。如果您需要跨多个函数调用(例如列表或树中的节点)持久化某些内容,这一点很重要

已分配
存储持续时间的对象(即,使用
malloc
calloc
realloc
从堆中分配的对象)将一直存在,直到您显式解除分配它们(
free

2-更改堆栈限制并使其变大有哪些缺点

您正在假设底层实现可以支持什么,这可能会限制您将代码移植到其他平台的能力(这可能是您关心的问题,也可能不是您关心的问题)。您还可以用帧大小换取堆栈深度—如果您为每个函数调用留出更多的空间,那么堆栈空间会更快用完,这对于深度嵌套调用或递归算法1可能很重要

这就是为什么通常的做法是动态分配非常大的对象,或者使它们
成为静态的


  • 诚然,在具有数千GB虚拟地址空间的现代托管实现上,这并不是一个主要问题,但在嵌入式平台或其他内存受限的环境中可能是一个问题。请记住,C是20世纪70年代早期的产物,当前的许多实践都是在总内存以KB为单位的系统上开发的。
    从我的头脑中可以看出一个原因(假设你的前提是正确的)——堆可以被释放,不管分配的块在哪里。堆栈只能从中“弹出”。这就是堆允许碎片,堆栈不允许碎片。谢谢,但在我的问题中,我提到“当我担心大小时”,我知道heapHow的其他优点,例如,你会检测堆栈溢出吗?您没有这样的机制(非恶性崩溃除外)。对于堆,你确实有这些。是的,但是如果我想让程序更快,并且有用户输入会溢出堆栈,并且我已经知道我的程序将达到的大小限制,那该怎么办?嗯,这里有一些移动的目标柱。如果你能让你的程序只被堆栈所容纳——尽管你说你知道它的缺点——那么去做吧