1. 运行环境
go version go1.15.4 linux/amd64
2. 问题描述?
package main
import (
"fmt"
)
func main() {
b := new(map[int]string)
fmt.Printf("b: %p\n", b)
fmt.Printf("&b: %p\n", &b)
c := make(map[int]string)
fmt.Printf("c: %p\n", c)
fmt.Printf("&c: %p\n", &c)
}
/*
打印结果
b: 0xc0000ba020
&b: 0xc0000ba018
c: 0xc000098150
&c: 0xc0000ba030
*/
上述代码中打印的b和&b,c和&c为什么不一样呢?
b和c是变量b和c的地址,那另外两个是什么地址,有什么特殊含义吗?
补充
func (p *pp) printArg(arg interface{}, verb rune) {
...
switch verb {
case 'T':
p.fmt.fmtS(reflect.TypeOf(arg).String())
return
case 'p':
p.fmtPointer(reflect.ValueOf(arg), 'p')
return
}
...
}
func (p *pp) fmtPointer(value reflect.Value, verb rune) {
var u uintptr
switch value.Kind() {
case reflect.Chan, reflect.Func, reflect.Map, reflect.Ptr, reflect.Slice, reflect.UnsafePointer:
u = value.Pointer()
default:
p.badVerb(verb)
return
}
...
}
上述是一段fmt.Printf在打印%p时候的一段源码,可以看出,当打印数据为符合类型,函数,指针的时候%p返回的就是当前值的指针,也就是上述打印的b和c即为变量指针。 这时候&b和&c也就成为了指向指针变量的指针地址。
疑问:程序在打印&b和&c这两行时是否真正的分配内存空间了呢?
观察到的现象:从多次执行结果看,b与&b的地址总相差2(16进制),c与&c却相差甚远。(可能跟make和new的源码有关系)
// new的源码返
func newobject(typ *_type) unsafe.Pointer
// makemap的源码
func makemap_small() *hmap
复合类型
变量地址