栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

二维数组的内存表示如何

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

二维数组的内存表示如何

在Go中,通常将slice误认为是array,所以我对两者都作了回答。

数组

引用规范:数组类型:

数组类型始终是一维的, 但可以组成多维类型。

在那里,您的答案清晰明了。但是答案不只是因为数组是Go中的值,它们也不像切片一样是描述符(标头)。

看这个简单的例子:

x := [5][5]byte{}fmt.Println(&x[0][3])fmt.Println(&x[0][4])fmt.Println(&x[1][0])

输出(在Go Playground上尝试):

0x104322030x104322040x10432205

如您所见,为数组分配和使用的内存是连续的:第二行从内存地址开始,该地址是第一行最后一个元素的地址的后继地址。

检查数组大小:

fmt.Println(unsafe.Sizeof([4][6]int{})) // 96fmt.Println(unsafe.Sizeof([6][4]int{})) // 96

切换行和列无关紧要,其大小相同。

切片

在切片的情况下也是如此:多维切片是切片的切片。规格:切片类型:

切片是 基础数组 连续段的描述符,并提供对该数组中元素编号序列的访问。

像数组一样,切片始终是一维的,但可以组成更高维度的对象。

切片是描述符,切片头包含指向基础(支持)数组的元素,长度和容量的指针。因此,总片数取决于内存使用情况。

请参阅以下示例:

x := make([][]byte, 2)for i := range x {    x[i] = make([]byte, 1000)}fmt.Println(len(x), len(x)*len(x[0]))y := make([][]byte, 1000)for i := range y {    y[i] = make([]byte, 2)}fmt.Println(len(y), len(y)*len(y[0]))

输出(在Go Playground上尝试):

2 20001000 2000

x
y
多维片具有2000个元素总(2000个字节),但
x
存储
2
仅切片,每个具有
1000
元件,而
y
存储
1000
切片,每个具有
2
元件。

这意味着

x
需要
2
片头,同时
y
需要
1000
切片头(用于元素+1
x
y
自己)!

切片标头表示为

reflect.SliceHeader

type SliceHeader struct {    Data uintptr    Len  int    Cap  int}

在32位架构上,切片标头的大小为12个字节,在64位架构上,其为24个字节。因此,对于32位arch元素,

x
要求2,000字节加上2x12字节的内存(即
2,024字节) ,而元素的
y
要求2,000字节加上1,000 * 12的 14,000字节

另请注意,多维切片的元素可能包含具有不同长度的切片:

对于数组数组,内部数组通过构造始终具有相同的长度;但是,对于切片的切片(或切片的阵列),内部长度可能会动态变化。此外,内部切片必须单独初始化。

像这个例子一样:

x := make([][]byte, 2)x[0] = []byte{1, 2}x[1] = []byte{1, 2, 3, 4}fmt.Println(x[0])fmt.Println(x[1])

输出(在Go Playground上尝试):

[1 2][1 2 3 4]

如果您还没有读过,推荐您:The Go Blog:数组,切片(和字符串):“
append”的机制



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/447973.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号