2

I'm want to understand what happens when created an empty slice with make([]int, 0). I do this code for test:

emptySlice := make([]int, 0)
fmt.Println(len(emptySlice))
fmt.Println(cap(emptySlice))
fmt.Println(unsafe.Sizeof(emptySlice))

The size and capacity return is obvious, both are 0, but the size of slice is 24 bytes, why?

24 bytes should be 3 int64 right? One internal array for a slice with 24 bytes should be something like: [3]int{}, then why one empty slice have 24 bytes?

phuclv
  • 32,499
  • 12
  • 130
  • 417
Vinicius Gabriel
  • 219
  • 1
  • 13

2 Answers2

11

All data types in Go are statically sized. By the nature of slices being dynamic, the number of elements is not associated with the type in any way.

If you read the documentation for unsafe.Sizeof, it explains what's going on here:

The size does not include any memory possibly referenced by x. For instance, if x is a slice, Sizeof returns the size of the slice descriptor, not the size of the memory referenced by the slice.

Hymns For Disco
  • 4,865
  • 2
  • 11
  • 28
5

unsafe.Sizeof is the size of the object in memory, exactly the same as sizeof in C and C++. See How to get memory size of variable?

A slice has size, but also has the ability to resize, so the maximum resizing ability must also be stored somewhere. But being resizable also means that it can't be a static array but needs to store a pointer to some other (possibly dynamically allocated) array

The whole thing means it needs to store its { begin, end, last valid index } or { begin, size, capacity }. That's a tuple of 3 values which means its in-memory representation is at least 3×8 bytes on 64-bit platforms, unless you want to limit the maximum size and capacity to much smaller than 264 bytes

It's exactly the same situation in many C++ types with the same dynamic sizing capability like std::string or std::vector is also a 24-byte type although on some implementations 8 bytes of padding is added for alignment reasons, resulting in a 32-byte string type. See

In fact golang's strings.Builder which is the closest to C++'s std::string has size of 32 bytes. See demo

phuclv
  • 32,499
  • 12
  • 130
  • 417