search

Home  >  Q&A  >  body text

c++ - c语言中的内存分配

这个问题是关于c和c++中对于参数,变量在内存中地址分配的问题。对于以下代码

int main (int argc, char *argv[]) {
  int a;
  int b;
  a = 1;
  b = 2;
  return 0;
}

我的理解是,main函数是通过初始函数调用,main函数实际和其他函数一样。
在初始函数调用main函数后,会先将返回地址压入堆栈,接着将参数压入堆栈。面对函数中定义的局部变量,将会按照定义顺序分配堆栈内存空间。而堆栈是从高地址向低地址生长的,所以我认为&a > &b。
然而,在gdb调试过程中,我发现&b > &a。请问我的理解在哪里错了?

PHPzPHPz2804 days ago575

reply all(4)I'll reply

  • 大家讲道理

    大家讲道理2017-04-17 11:06:28

    The space of local variables is not pushed onto the stack one by one, but is allocated once, so it is wrong to understand that the variables are pushed onto the stack one by one. The C language does not stipulate the location of local variables in memory, but is often implemented as variables defined first are at high addresses and variables defined later are at low addresses. However, there is no absolute relationship between the position of local variables on the stack, and they may not even appear on the stack. For example, if you make this adjustment to your code, change it to the following:

    #include<stdio.h>
    
    int main()
    {
      int a = 1;
      int b = 2;
    
      printf( "a = %d, b = %d\n", a, b );
      printf( "&a = %08x, &b = %08x\n", &a, &b );
      return 0;
    }

    At this time you will find that variable a is indeed allocated at a high address, while variable b is allocated at a low address. If you optimize your program with the -O2 parameter, then the two variables a and b will be optimized by the compiler because they are not really used, and you will not get any value directly by p & a.

    reply
    0
  • 怪我咯

    怪我咯2017-04-17 11:06:28

    The "stack" data structure itself does not stipulate the direction of its growth. It does not matter whether it grows to a high address or a low address in the specific implementation. But for the operating system, the growth direction of the stack generally depends on the processor's implementation of PUSH/POP operations. For x86, the value of SP/ESP decreases after PUSH, so it grows towards lower addresses. Sample code:

    #include <stdio.h>
    
    void stack_growth(char *function_parameter) {
        char local;
        if (&local > function_parameter)
            printf("up\n");
        else
            printf("down\n");
        printf("%p %p\n", &local, function_parameter);
    }
    
    int main()
    {
        char c = 'c';
        stack_growth(&c);
        return 0;
    }

    Declaring a variable is nothing more than telling the compiler to prepare a space for it on the stack. Therefore, the situation you mentioned is actually not directly related to the stack: if a is declared first, will it be allocated space for it on the stack first? To give the simplest example, if a is not used at all, the compiler does not need to allocate space for it. So this ultimately depends on the implementation of the compiler.

    Add a WIKI:

    Some processors families, such as the x86, have special instructions for manipulating the stack of the currently executing thread. Other processor families, including PowerPC and MIPS, do not have explicit stack support, but instead rely on convention and delegate stack management to the operating system's Application Binary Interface (ABI).

    reply
    0
  • 天蓬老师

    天蓬老师2017-04-17 11:06:28

    The memory area allocated by the system is called the "stack area", and the memory space allocated manually is called the "heap area".
    In the "stack area", the address expansion direction is from high address to low address, and in the "heap area" it is the opposite.

    reply
    0
  • 阿神

    阿神2017-04-17 11:06:28

    lz Can you post the compilation command?

    reply
    0
  • Cancelreply