0

我有以下 C 代码:

// test.c
#include <stdio.h>
#include <stdlib.h>

int main() {
  printf("location of code    : %p\n", (void *)main);
  void *heap = malloc(1);
  printf("location of heap    : %p\n", heap);
  int stack = 3;
  printf("location of stack   : %p\n", (void *)&stack);
  return 0;
}

gcc我通过和编译这段代码clang

gcc test.c -o test1
clang test.c -o test2

两个程序都按预期运行,输出如下内容:

location of code    : 0x101b95ec0
location of heap    : 0x7fecde5041c0
location of stack   : 0x7ffeee06a6b8

这表明,堆的起始位置更接近堆栈而不是代码。

但是,如果我使用 Xcode GUI 编译此代码,则输出类似于:

location of code    : 0x100000ec0
location of heap    : 0x100610b10
location of stack   : 0x7ffeefbff70c

我知道 Xcodeclang用作编译器,但输出令人困惑。Xcode 会做一些事情来限制堆大小,还是做其他事情?

4

1 回答 1

0

用函数调用修改它似乎是同样的问题。但是将堆大小增加到更大(10000000000 然后 100000000000 又一个零),您可能会注意到从 0xf... 回到 0x1... 的变化仍然很奇怪。


#include <stdio.h> 
#include <stdlib.h>
#define HEAPSIZE 10000000000 // 100000000000 one more zero trigger 0x1 to 0x7


// https://www.geeksforgeeks.org/memory-layout-of-c-program/
// https://stackoverflow.com/questions/62906466/why-c-program-compiled-in-xcode-has-strange-memory-layout


//1
int global; /* Uninitialized variable stored in bss*/
int global2 = 10; 

void test1(int stack);

void test1(int stack){
    stack = 4;
    printf("location of stack      - %p and %d\n", (void *)&stack, stack);

}

void test2(int *stack);

void test2(int *stack){
    * stack = 4;
    printf("location of stack      - %p and %d\n", (void *)stack, *stack);

}

int main(void) 
{ 
    //2 
    static int i; /* Uninitialized static variable stored in bss */
    //3a
    static int j = 100; /* Initialized static variable stored in DS*/

    printf("location of global2    : %p\n", (void *)&global2);
    
    printf("location of static j   : %p\n", (void *)&j);
    
    printf("location of code       : %p\n", (void *)main);
    void *heap = malloc(HEAPSIZE * sizeof(int)); // malloc(1);
    printf("location of heap       : %p\n", heap);
    printf("location of heap end   : %p\n", heap + HEAPSIZE - 1);
    int var = 3;
    printf("location of var        : %p and %d\n", (void *)&var, var);

    test1(var);
    printf("location of test1(var) : %p and %d\n", (void *)&var, var);

    test2(&var);
    printf("location of test2(var) : %p and %d\n", (void *)&var, var);


    return 0; 

    // check size -xml M
} 

10000000000个案例

location of global2    : 0x10ea54018
location of static j   : 0x10ea5401c
location of code       : 0x10ea52d40
location of heap       : 0x7fa29ac00000
location of heap end   : 0x7fa4eecbe3ff
location of var        : 0x7ffee11ada7c and 3
location of stack      - 0x7ffee11ada3c and 4
location of test1(var) : 0x7ffee11ada7c and 3
location of stack      - 0x7ffee11ada7c and 4
location of test2(var) : 0x7ffee11ada7c and 4

100000000000 例(多一个零)

location of global2    : 0x10cf8e018
location of static j   : 0x10cf8e01c
location of code       : 0x10cf8cd40
location of heap       : 0x115b3a000
location of heap end   : 0x185e2a87ff
location of var        : 0x7ffee2c73a7c and 3
location of stack      - 0x7ffee2c73a3c and 4
location of test1(var) : 0x7ffee2c73a7c and 3
location of stack      - 0x7ffee2c73a7c and 4
location of test2(var) : 0x7ffee2c73a7c and 4

您可能会注意到函数变量(不使用指针的变量)仍然是 0x7ff...

尝试铿锵的行为是相同的变化。

但是额外 0 的变化不会触发 Xcode 的任何变化,并且总是 0x1....

Mac下docker ubuntu 20下试试,触发点是#define HEAPSIZE 10000 // 10000 0x5 // 100000 0x7

非常混乱。

root@4519bf65652d:/src/testxcode.c2# make m
cc -g -o M m.c 
root@4519bf65652d:/src/testxcode.c2# make mr
size -x ./M
   text    data     bss     dec     hex filename
  0x9e9   0x270    0x10    3177     c69 ./M
size ./M
   text    data     bss     dec     hex filename
   2537     624      16    3177     c69 ./M
./M
location of global2    : 0x5577dac6d010
location of static j   : 0x5577dac6d014
location of code       : 0x5577dac6a1f8
location of heap       : 0x7fa282247010
location of heap end   : 0x7fa28225f6af
location of var        : 0x7ffd1a9826dc and 3
location of stack      - 0x7ffd1a9826bc and 4
location of test1(var) : 0x7ffd1a9826dc and 3
location of stack      - 0x7ffd1a9826dc and 4
location of test2(var) : 0x7ffd1a9826dc and 4
root@4519bf65652d:/src/testxcode.c2# make m 
cc -g -o M m.c 
root@4519bf65652d:/src/testxcode.c2# make mr
size -x ./M
   text    data     bss     dec     hex filename
  0x9e9   0x270    0x10    3177     c69 ./M
size ./M
   text    data     bss     dec     hex filename
   2537     624      16    3177     c69 ./M
./M
location of global2    : 0x56297cec6010
location of static j   : 0x56297cec6014
location of code       : 0x56297cec31f8
location of heap       : 0x56297d9516b0
location of heap end   : 0x56297d953dbf
location of var        : 0x7ffe0bbaac8c and 3
location of stack      - 0x7ffe0bbaac6c and 4
location of test1(var) : 0x7ffe0bbaac8c and 3
location of stack      - 0x7ffe0bbaac8c and 4
location of test2(var) : 0x7ffe0bbaac8c and 4
root@4519bf65652d:/src/testxcode.c2# 
于 2020-08-07T10:06:06.863 回答