You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Go语言中string与[]byte的unsafe.Sizeof结果为何不符合预期?

Why string and []byte Show Larger Sizes Than Expected in Go

Great question—this is a super common gotcha when you're working with Go's memory layout, so let's unpack it step by step.

First, let's clarify what unsafe.Sizeof() actually does: it returns the size of the variable itself in memory, not the size of the data that the variable points to. That's the key misunderstanding here—you were expecting it to return the number of bytes in your string/slice content, but it's measuring the underlying struct that Go uses to represent these types.

Let's break down each type:

  • string in Go: A string is implemented as a small struct with two fields:

    1. A pointer to the underlying read-only byte array that holds the actual string data (8 bytes on 64-bit systems)
    2. An integer representing the length of the string (another 8 bytes)
      Adding those together gives 16 bytes total, which matches your output. The actual "fool" bytes (4 bytes) are stored elsewhere (usually in the executable's read-only section or the heap), but Sizeof() doesn't count that—it only measures the struct that references the data.
  • []byte (slice) in Go: A slice is an even slightly larger struct with three fields:

    1. A pointer to the underlying byte array (8 bytes)
    2. An integer for the slice's current length (8 bytes)
    3. An integer for the slice's capacity (the total space allocated in the underlying array, another 8 bytes)
      That adds up to 24 bytes, which is exactly what you saw. Again, the 4 bytes of "fool" are in the underlying array, not part of the slice struct itself.

To get the size of the actual content, use len() (and cap() for slices)

If you want to measure the number of bytes in your string or slice content, use the built-in len() function instead. For slices, cap() will tell you the total capacity of the underlying array. Here's how that looks with your code:

package main

import (
	"fmt"
	"unsafe"
)

func main() {
	c := "fool"
	d := []byte("fool")
	fmt.Printf("c: %T, Sizeof: %d, content length: %d\n", c, unsafe.Sizeof(c), len(c))
	// Output: c: string, Sizeof: 16, content length: 4

	fmt.Printf("d: %T, Sizeof: %d, content length: %d, capacity: %d\n", d, unsafe.Sizeof(d), len(d), cap(d))
	// Output: d: []uint8, Sizeof: 24, content length: 4, capacity: 4
}

Quick recap

  • unsafe.Sizeof() measures the memory taken by the type's struct (pointer + metadata), not the referenced data
  • Strings are 2-field structs (pointer + length) → 16 bytes on 64-bit systems
  • Slices are 3-field structs (pointer + length + capacity) → 24 bytes on 64-bit systems
  • Use len() to get the actual number of bytes in your string or slice content

内容的提问来源于stack exchange,提问作者overexchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 05:30:09