2012-02-05 wcdj
1, 调试时必需的栈知识
2, 数组非法访问导致内存破坏
调试时必需的栈知识
栈(stack)是程序存放数据的内存区域之一,其特征是LIFO(Last In First Out, 后进先出)式数据结构,即后放进的数据最先备取出。向栈中存储数据的操作称为PUSH(压入),从栈中取出数据称为POP(弹出)。在保存动态分配的自动变量时要使用栈。此外在函数调用时,栈还用于传递函数参数,以及用于保存返回地址和返回值。
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#define MAX (1UL << 20)
typedef unsigned long long u64;
typedef unsigned int u32;
u32 max_addend = MAX;
u64 sum_till_MAX(u32 n)
{
u64 sum;
n++;
sum = n;
if (n < max_addend)
sum += sum_till_MAX(n);
return sum;
}
int main(int argc, char** argv)
{
u64 sum = 0;
if ((argc == 2) && isdigit(*(argv[1])))
max_addend = strtoul(argv[1], NULL, 0);
if (max_addend > MAX || max_addend == 0) {
fprintf(stderr, "Invalid number is specified\n");
return 1;
}
sum = sum_till_MAX(0);
printf("sum(0..%lu) = %llu\n", max_addend, sum);
return 0;
}
计算从0到10的总和:
$ gcc -o sum -g sum.c
$ ./sum 10
sum(0..10) = 55
函数调用和栈的关系 —— 函数调用前后栈的变化情况
栈上依次保存了传给函数的参数、调用者的返回地址、上层栈帧指针和函数内部使用的自动变量。此外,处理有些函数时还会用栈来临时保存寄存器。每个函数都独自拥有这些信息,称为栈帧(stack frame)。此时需要适当地设置表示栈帧起始地址的帧指针(FP)。此外,