dsf6281 2014-12-25 13:43
浏览 715
已采纳

Go中切片的最大长度

I have the following code running in a 64-bit linux OS in a 4Gb machine:

package main

import (
    "fmt"
    "math"
)

func main() {
    r := make([]bool, math.MaxInt32)

    fmt.Println("Size: ", len(r))
}

When I run this I get:

Size: 2147483647

If I change the math.MaxInt32 for math.MaxUint32 I get:

fatal error: runtime: out of memory

With slice size of math.MaxUint32 I ran out of memory, I was expecting that, but when I try using math.MaxInt64 I get:

panic: runtime error: makeslice: len out of range

So aparently I cannot create a slice with a size of math.MaxInt64, which bring us to my question: If the memory is not an issue, what's the biggest slice I cant create in Go?

I remember that, in Java, raw array indexes are managed with the type int, so the maximum size of a raw array is the max value of an int, if you try to do it with long it will raise an exception (as far as I remember), is it the same with Go? are slice index in Go bound to one specific type?

EDIT:

I ran the test using struct{} instead of bool and allocating math.MaxInt64 elements. Everything went as expected, and prints:

Size: 9223372036854775807

So, another question, why there are two different error messages when it seems that the error is the same (not enough memory)?

What are the conditions for each error to pop out?

  • 写回答

1条回答 默认 最新

  • doutuoben6908 2014-12-25 13:51
    关注

    According to the docs, The elements can be addressed by integer indices 0 through len(s)-1. This means the maximum capacity for a slice is the size of the default integer on the target build.

    EDIT: From looking at the source code, it appears that there is a safety check to make sure this size of slice is at all possible:

    func makeslice(t *slicetype, len64 int64, cap64 int64) sliceStruct {
        // NOTE: The len > MaxMem/elemsize check here is not strictly necessary,
        // but it produces a 'len out of range' error instead of a 'cap out of range' error
        // when someone does make([]T, bignumber). 'cap out of range' is true too,
        // but since the cap is only being supplied implicitly, saying len is clearer.
        // See issue 4085.
        len := int(len64)
        if len64 < 0 || int64(len) != len64 || t.elem.size > 0 && uintptr(len) > maxmem/uintptr(t.elem.size) {
            panic(errorString("makeslice: len out of range"))
        }
    

    So in this case, it looks like uintptr(len) > maxmem/uintptr(t.elem.size) so we're not allowed to do this size of an allocation.

    However when I allocate struct{} which takes no memory, this size is allowed:

    func main(){
        r := make([]struct{}, math.MaxInt64)
        fmt.Println(len(r))
    }
    // prints 9223372036854775807
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥50 如何使用js去调用vscode-js-debugger的方法去调试网页
  • ¥15 376.1电表主站通信协议下发指令全被否认问题
  • ¥15 物体双站RCS和其组成阵列后的双站RCS关系验证
  • ¥15 复杂网络,变滞后传递熵,FDA
  • ¥20 csv格式数据集预处理及模型选择
  • ¥15 部分网页页面无法显示!
  • ¥15 怎样解决power bi 中设置管理聚合,详细信息表和详细信息列显示灰色,而不能选择相应的内容呢?
  • ¥15 QTOF MSE数据分析
  • ¥15 平板录音机录音问题解决
  • ¥15 请问维特智能的安卓APP在手机上存储传感器数据后,如何找到它的存储路径?