Golang 切片详解一 内存布局

   日期:2020-05-09     浏览:98    评论:0    
核心提示:package mainimport ( fmt unsafe)func main() { fmt.Println() // 切片 // 创建一个切片给变量a,这个切片的长度为0,其底层数组长度为8(常称之为容量) // 切片a的数据结构 struct{ptr: 0x0, len: 0, cap: 8} 占用24字节(72位) // ptr:占8字节 是一个指针 ...golang

 不说废话,直接上货,能懂则懂,不能懂则略过

package main

import (
	"fmt"
	"unsafe"
)

func main() {

	fmt.Println()

	// 切片
	// 创建一个切片给变量a,这个切片的长度为0,其底层数组长度为8(常称之为容量)
	// 切片a的数据结构 struct{ptr: 0x0, len: 0, cap: 8} 占用24字节(72位)
	// ptr:占8字节 是一个指针 存储的是底层数组的内存地址
	// len:占8字节 是切片的长度
	// cap: 占8字节 是底层数组的长度
	a := make([]int8, 0, 10)
	b := append(a, 2)
	_ = append(a, 3)
	_ = append(a, []int8{4, 5}...)
	_ = append(a, []int8{4, 5, 6}...)
	_ = append(a, []int8{4, 5, 6, 7}...)

	// 切片a的数据结构
	ptra := (*uint64)(unsafe.Pointer(&a))                                  // 占8字节 指向的是底层数组
	ptral := *(*int64)(unsafe.Pointer(uintptr(unsafe.Pointer(ptra)) + 8))  // 占8字节 切片的长度
	ptrac := *(*int64)(unsafe.Pointer(uintptr(unsafe.Pointer(ptra)) + 16)) // 占8字节 切片的容量

	fmt.Printf("切片a的地址:%#x 底层数组:0x%x 长度:%d 容量:%d 数据:%v\n", ptra, *ptra, ptral, ptrac, a)
	// 切片a的地址:0xc00011c460 底层数组:0xc000126090 长度:0 容量:10 数据:[]

	// 切片b的数据结构
	ptrb := (*uint64)(unsafe.Pointer(&b))                                  // 占8字节 指向的是底层数组
	ptrbl := *(*int64)(unsafe.Pointer(uintptr(unsafe.Pointer(ptrb)) + 8))  // 占8字节 切片的长度
	ptrbc := *(*int64)(unsafe.Pointer(uintptr(unsafe.Pointer(ptrb)) + 16)) // 占8字节 切片的容量

	fmt.Printf("切片b的地址:%#x 底层数组:0x%x 长度:%d 容量:%d 数据:%v\n", ptrb, *ptrb, ptrbl, ptrbc, b)
	// 切片b的地址:0xc00011c480 底层数组:0xc000126090 长度:1 容量:10 数据:[4]

	p := uintptr(*ptra)
	for i := int64(0); i < ptrac; i++ {
		p := (*int8)(unsafe.Pointer(p + uintptr(i)))
		fmt.Printf("addr:%p key: %d val: %v\n", p, i, *p)
	}
	// 底层数组
	// addr:0xc000126090 key: 0 val: 4
	// addr:0xc000126091 key: 1 val: 5
	// addr:0xc000126092 key: 2 val: 6
	// addr:0xc000126093 key: 3 val: 7
	// addr:0xc000126094 key: 4 val: 0
	// addr:0xc000126095 key: 5 val: 0
	// addr:0xc000126096 key: 6 val: 0
	// addr:0xc000126097 key: 7 val: 0
	// addr:0xc000126098 key: 8 val: 0
	// addr:0xc000126099 key: 9 val: 0

	fmt.Printf("\n")
}

 

 

 

 

 

 

 

 

综上述:

  1. 切片是一个数据结构体,拥有3段数据,每段占8字节,共占24字节。
  2. 第一段,存储切片的底层数组所在的内存地址,即指针
  3. 第二段,存储着切片的长度,即切片本身的长度
  4. 第三段,存储着切片的容量,即底层数组的长度
 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
更多>相关资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服