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

#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----
down

Process returned 0 (0x0)   execution time : 0.640 s
Press 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 than m2 or not depends heavily on the memory allocation method.

你可能感兴趣的:(C++,c,栈,cc++,笔试面试)