程序中的函数调用栈是栈数据结构的一种应用
函数调用栈一般是从高地址向低地址增长
·栈顶为内存的低地址
·栈底为内存的高地址
函数调用栈中的存储数据为活动记录
活动记录:函数调用时一系列相关记录
程序栈空间:
·本质上是顺序栈
·程序栈空间访问是通过函数调用进行的
·程序栈空间遵循后进先出原则
参数 |
返回地址 |
Old EBP |
寄存器值 |
局部变量 |
其他上下文数据 |
局部变量存在在活动记录中,所以是在栈数据结构中
程序中的栈空间可以看成顺序栈的应用,栈保存了一个函数调用所维护信息
·函数参数,函数返回地址
·局部变量
·函数调用上下文
栈溢出:程序在不断压栈过程中造成栈空间耗尽而产生栈溢出
原因:递归过深/局部数组过大
递归举例
#include <stdio.h>
void reverse(char* s)
{
if( (s != NULL) && (*s != '\0') )
{
reverse(s + 1);
printf("%c", *s);
}
}
int main()
{
reverse("12345");
printf("\n");
return 0;
}
输出结果是54321
代码分析
活动记录 main |
S->”12345” *s=1 |
S->”2345” *s=2 |
S->”345” *s=3 |
S->”45” *s=4 |
S->”5” *s=5 |
S->’\0’ *s=\0 |
条件不能满足就要退栈,从栈顶将活动记录弹出
程序工作过程
int main (void)
{
reserve (12345)
{
reserve(2345)
{
reserve(345)
{
reserve(45)
{
reserve (5)
{
printf (5)
}
printf (4)
}
printf (3)
}
printf (2)
}
printf (1)
}
}
所以结果输出为54321