draveness / blog-comments

面向信仰编程
https://draveness.me
140 stars 6 forks source link

请问如何打印出数组变量在栈上的地址? #653

Closed codlin closed 1 year ago

codlin commented 2 years ago

请问如何打印出数组变量在栈上的地址?

Go语言版:

package main

import (
    "fmt"
)

func main() {
    /* 声明一个长度为4的数组
    编译器会在编译时将其改写为:
    var a [4]int64
    &a[0] = 1
    &a[1] = 2
    &a[2] = 3
    &a[3] = 4
    即所有的元素都放置在栈上
    */
    a := [...]int{0, 1, 2, 3}
    p1 := &a[0]
    p2 := &a[1]
    p3 := &a[2]
    p4 := &a[3]

    // 0xc0000a0000 0xc0000a0008 0xc0000a0010 0xc0000a0018
        // 0xc000098018 0xc000098020 0xc000098028 0xc000098030
    fmt.Printf("%p %p %p %p\n%p %p %p %p", p1, p2, p3, p4, &p1, &p2, &p3, &p4)
}

按照书里说的,编译器会对小于等于4的数组改写,那么为什么打不出变量a在栈上的地址? 在我的机器上a数组应该是发生了逃逸,但我的理解应该存在一个局部变量的,或者是地址直接放在了寄存器?

C语言版:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int a[]={1, 2, 3};
    int *b = a;
    int *c = a;
    int *d = (int *)malloc(sizeof(int)*3);
    int *e = d;

    // a: 0x7ffe85a686f4    &a: 0x7ffe85a686f4  &b: 0x7ffe85a686e8  &c: 0x7ffe85a686e0
    printf("a: %p\t&a: %p\t&b: %p\t&c: %p\n", a, &a, &b, &c);

    // d: 0x207b260 &d: 0x7fffb98a0b88  &e: 0x7fffb98a0b80
    printf("d: %p\t&d: %p\t&e: %p\n", d, &d, &e);

    free(d);
    d = NULL;
    return 0;
}

对比C语言版本,a数组在栈上,打印的数组首地址就是在栈上的地址,d数组在堆上分配,打印&d可以看到变量d在栈上的地址

谢谢