35 language-agnostic stack-overflow stack
什么是堆栈溢出错误?它可能会出现什么类型的程序/编程语言?是否不太可能在Web应用程序代码中出现?
vic*_*ugo 26
来自维基百科:
在软件中,当在调用堆栈上使用太多内存时,会发生堆栈溢出.在许多编程语言中,调用堆栈包含有限的内存量,通常在程序开始时确定.
堆栈是一种数据结构,它记录程序的子程序在完成执行时应将控制权返回的点.在调用子程序时,返回地址被压入堆栈中,当子程序完成执行时,返回地址从堆栈中拉出.如果有很多子程序,并且堆栈中没有空间,则会发生堆栈溢出.
同样在堆栈中的目的是存储局部变量,因此如果局部变量太大,则更有可能堆栈没有空间来存储它,如果是这种情况也会发生堆栈溢出.
维基百科包含一个很好的图表,描绘了DrawLine从另一个子程序调用子程序时的堆栈DrawSquare,我希望这张图片有助于更好地理解堆栈结构.

堆栈溢出有两个主要原因:深层函数递归和过大的堆栈变量.由于这些是几乎所有编程语言中的常用术语,因此除了语言的复杂性之外,还可能发生堆栈溢出.
Guffa贡献:堆栈与垃圾收集没有任何关系.现代应用程序具有更大的堆栈,这使得堆栈溢出的可能性略微降低,但除此之外没有任何区别.
Sco*_*ham 18
堆栈包含许多堆栈帧并存储在内存中.每次调用函数时,都会向堆栈添加新的堆栈帧.堆栈帧包含要传递给被调用函数的参数和返回地址,这样当被调用函数完成时,cpu知道返回的位置,因此它可以继续执行调用函数.堆栈帧还可以包含要被调用的函数的局部变量使用的存储器.
在此示例中,Main函数名为WriteCustomerDetails,并调用PrintToConsole来写出WriteCustomerDetails函数查找的各个数据位:
'=======栈顶=====================' 
功能:PrintToConsole 
Arg:John Smith,34 Acacia Avenue,23岁
' - -------------------------------------------------- -------' 
功能:WriteCustomerDetails 
Arg:John Smith 
'---------------------------------- -------------------------' 
功能:主
'======堆栈底部=========== ========"  
如果没有保留堆栈的足够空间,则会发生堆栈溢出.通常堆栈位于一个大的连续内存块中,因此不会分成块,这意味着需要一块大内存,这使得运行时很难尝试增加为堆栈保留的空间如果它填满了.
当意外写入调用自身的函数时,通常会发生堆栈溢出.有时,只要函数中有一个"if"或某些条件在某个时刻停止调用,函数就可以调用自身.这称为递归函数.但是,如果没有停止并且函数一直在调用自身,或者两个或多个函数可能一直在相互调用,那么很快它们将会占用所有堆栈内存.当没有剩下的时候,你得到一个堆栈溢出,程序崩溃了.
这可能发生在任何程序中,它们不一定非常复杂,并且可能发生在运行网站的代码中.而且,它也可以在脚本语言中出现.
当您使用过多的堆栈空间时,会发生堆栈溢出.发生这种情况通常有两种情况:
第一种是当代码中出现错误时,导致没有退出的递归循环.例如,一个属性读取自己:
public int Length {
   get {
      return Length;
   }
}
第二个是你有一个太深的递归循环.由于堆栈空间有限,您只能将算法嵌套一定次数.如果您的算法嵌套太深,以至于它在堆栈空间存在之前耗尽,则会出现堆栈溢出.例:
public bool Odd(int value) {
   if (value == 0) {
      return false;
   } else {
      return !Odd(value - 1);
   }
}
如果使用太大的值调用此方法,它将嵌套太深并导致堆栈溢出.