Find out whether a pointer is pointing at the stack, heap or program text?

后端 未结 2 973
轻奢々
轻奢々 2020-12-09 03:48

Is there a way to find out whether a pointer is pointing at a location in:

  • the stack
  • the heap
  • or the program (and if so, which section e.g.
相关标签:
2条回答
  • 2020-12-09 04:14

    You cannot do what you want in a portable way, because the C language standard does not specify the stack, program area, and heap as distinct areas. Their location can depend on the processor architecture, the operating system, the loader, the linker, and the compiler. Trying to guess where a pointer is pointing is breaking the abstraction provided by C, so you probably you shouldn't be doing that.

    Nevertheless, there are ways to write code that will make a correct guess for a specific environment. You do that by examining the addresses of existing objects, and looking for patterns. Consider the following program.

    #include <stdlib.h>
    #include <stdio.h>
    
    void
    function()
    {
        int stack2;
    
        printf("stack2:  %15p\n", &stack2);
    }
    
    int
    main(int argc, char *argv[])
    {
        int stack;
        void *heap = malloc(1);
        void *heap2 = malloc(1);
    
        printf("program: %15p\n", main);
        printf("heap:    %15p\n", heap);
        printf("heap2:   %15p\n", heap2);
        printf("stack:   %15p\n", &stack);
        function();
        return 0;
    }
    

    By examining its output you can see a pattern, such as the following on x64 Linux.

    program:        0x400504
    heap:          0x1675010
    heap2:         0x1675030
    stack:    0x7fff282c783c
    stack2:   0x7fff6ae37afc
    

    From the above you can determine that (probably) the heap grows up from 0x1675010, anything below it is program code (or static data, which you didn't mention), and that the stack grows in an unpredictable manner (probably due to stack randomization) around a very large address, like 0x7fff282c783c.

    Compare this with the output under 32-bit Intel Linux:

    program:       0x804842f
    heap:          0x804b008
    heap2:         0x804b018
    stack:        0xbf84ad38
    stack2:       0xbf84ad14
    

    Microsoft Windows and the 32-bit Microsoft C compiler:

    program:        01271020
    heap:           002E3B00
    heap2:          002E3B10
    stack:          0024F978
    stack2:         0024F964
    

    gcc under Windows Cygwin:

    program:        0040130B
    heap:           00A41728
    heap2:          00A417A8
    stack:          0028FF44
    stack2:         0028FF14
    

    gcc under Intel 32-bit FreeBSD:

    program:       0x8048524
    heap:          0x804b030
    heap2:         0x804b040
    stack:        0xbfbffb3c
    stack2:       0xbfbffb1c
    

    gcc under Intel 64-bit FreeBSD:

    program:        0x400770
    heap:        0x801006058
    heap2:       0x801006060
    stack:    0x7fffffffdaec
    stack2:   0x7fffffffdabc
    

    gcc under SPARC-64 FreeBSD:

    program:        0x100860
    heap:         0x40c04098
    heap2:        0x40c040a0
    stack:     0x7fdffffe9ac
    stack2:    0x7fdffffe8dc
    

    PowerPC running MacOS X:

    program:          0x1ed4
    heap:           0x100120
    heap2:          0x100130
    stack:        0xbffffba0
    stack2:       0xbffffb38
    

    PowerPC running Linux:

    program:      0x10000514
    heap:         0x100c6008
    heap2:        0x100c6018
    stack:        0xbff45db0
    stack2:       0xbff45d88
    

    StrongARM running NetBSD:

    program:          0x1c5c
    heap:             0x5030
    heap2:            0x5040
    stack:        0xefbfdcd0
    stack2:       0xefbfdcb4
    

    and ARMv6 running Linux:

    program:          0x842c
    heap:           0xb63008
    heap2:          0xb63018
    stack:        0xbe83eac4
    stack2:       0xbe83eaac
    

    As you can see the possibilities are endless.

    0 讨论(0)
  • 2020-12-09 04:26

    You can determine the location generally speaking of the stack and heap, though how large it is will be another story...

    void *heap_locations;
    void *stack_location;
    
    void determine_locations (int any_int) {
       free(heap_location = malloc(248));
       stack_location = &any_int;
    }
    
    int main(int argc, char *argv[]) {
      determine_locations(argc);
          .
          .
          .
      return 0;
    }
    

    A bit rude and you won't know the expansion direction or size of either for absolute sure unless you are dealing with specified platforms.

    0 讨论(0)
提交回复
热议问题