四种方法判断栈的生长方向 Determine the Direction of Stack Growth

来源:互联网 发布:暗夜情缘 知乎 编辑:程序博客网 时间:2024/05/08 15:21

#include<cstdio>#include<cstdlib>#include<iostream>using std::cout;static void find_stack_direction(void);static int stack_dir;static void stack_growth_v1(void){    static char *addr = NULL; /* address of first`dummy', once known */    auto char dummy; /* to get stack address */    if (addr == NULL)    { /* initial entry */        addr = &dummy;        stack_growth_v1 (); /* recurse once */    }    else if (&dummy > addr)/* second entry */        stack_dir = 1; /* stack grew upward */    else        stack_dir = -1; /* stack grew downward */}void stack_growth_v2(char *function_parameter){    char local;    if (&local > function_parameter)        printf("up\n");    else        printf("down\n");}void stack_growth_v3(volatile char *function_parameter){    volatile char local [64];    if (&local [63] > function_parameter)        printf("up\n");    else        printf("down\n");}void stack_growth_v4(){    char *m1 = (char *)malloc(2);    char *m2 = (char *)malloc(2);    if (m2 > m1)        printf("down\n");    else        printf("up\n");}int main(void){    cout<<"---------stack_growth_v1----\n";    stack_growth_v1();    if(stack_dir==1)        puts("stack grew upward");    else        puts("stack grew downward");    cout<<"---------stack_growth_v2----\n";    char c = 'c';    stack_growth_v2(&c);    cout<<"---------stack_growth_3----\n";    volatile char d[64];    stack_growth_v3(&d[63]);    cout<<"---------stack_growth_4----\n";    stack_growth_v4();    return 0;}/***********************运行结果:---------stack_growth_v1----stack grew downward---------stack_growth_v2----down---------stack_growth_3----down---------stack_growth_4----downProcess returned 0 (0x0)   execution time : 0.640 sPress any key to continue.************************/




A simple way to determine the direction of stack growth is to compare the address of a function parameter with the address of a local variable in the function. Of course, the main difficulty here is to avoid compiler optimization, such as register variables, function inlining, and so on. So, the first attempt may look like the following function:

void stack_growth(char *function_parameter) {    char local;    if (&local > function_parameter)        printf("up\n");    else        printf("down\n");}
The above code can be called as follows:
char c = 'c'; stack_growth(&c);
This example can be improved by using volatile modifiers and changing scalar variables into arrays:
void stack_growth(volatile char *function_parameter) {    volatile char local [64];    if (&local [63] > function_parameter)        printf("up\n");    else        printf("down\n");}
and calling this function as follows:
volatile char c[64]; stack_growth(&c[63]); 

It is also possible to find out the direction of stack growth by noting that it is the opposite of the heap growth direction (stack and heap usually grow towards each other), but this method is not very reliable either. For example, take the following code:

char *m1 = (char *)malloc(2);char *m2 = (char *)malloc(2);
Whether m1 will be greater thanm2 or not depends heavily on the memory allocation method.