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

Go语言字符串切片的内存表示解析:元素地址间隔原因探究

Go语言字符串切片的内存表示方式

先看你给出的C语言示例,理解C中字符串数组的内存布局:

#include <stdio.h>

int main(int argc, char **argv) {
  char *x[3];
  x[0] = "hi";
  x[1] = "foo";
  x[2] = "bar";
  printf("%p\n", x[0]);
  printf("%p\n", x[1]);
  printf("%p\n", x[2]);
}

运行输出:

0x1068d0fa0
0x1068d0fa3
0x1068d0fa7

对应的内存布局:

0x1068d0fa0 -> h
0x1068d0fa1 -> i
0x1068d0fa2 -> '\0'
0x1068d0fa3 -> f
0x1068d0fa4 -> ... 直到x[2]的最后一个字符,彼此间隔1字节

可以看到C中字符串字面量的内容会被编译器优化到连续的内存区域,数组里存储的是指向这些连续内容的指针。

再看你给出的Go语言示例:

package main

import (
    "fmt"
)

func main() {
    k := []string{"hi", "there", "how", "are", "you"}

    fmt.Printf("\n%p", &k[0])
    fmt.Printf("\n%p", &k[1])
    fmt.Printf("\n%p", &k[2])
    fmt.Printf("\n%p", &k[3])
    fmt.Printf("\n%p", &k[4])
}

运行输出显示元素地址间隔为16字节(你给出的10字节应为笔误,64位系统下标准间隔是16字节):

0x430050
0x430060
0x430070
0x430080

Go语言的内存表示逻辑

1. string类型的本质

Go中的string不是单纯的指针,而是一个固定大小的结构体:

  • 在64位系统下占16字节,包含两个字段:
    • ptr:8字节指针,指向存储字符串内容的底层字节数组
    • len:8字节整数,记录字符串的字节长度
  • 在32位系统下占8字节(4字节指针+4字节长度)

2. 字符串切片([]string)的布局

字符串切片本身也是一个结构体,包含三个核心字段:

  • ptr:指向底层元素数组的指针
  • len:切片当前包含的元素数量
  • cap:底层数组的最大容量

切片的底层数组中,每个元素就是上述的string结构体,所以在64位系统中,数组里每个元素占16字节,这就是相邻元素地址间隔为16字节的原因。

3. 和C语言的核心差异

  • C的字符串数组存储的是指向字符串内容的指针,字面量内容通常连续;
  • Go的字符串切片底层数组存储的是string结构体(指针+长度),每个结构体的ptr指向的字符串内容,在内存中不一定连续(编译器可能会合并字面量,但没有强制要求)。

简单来说:Go切片的元素(string结构体)是连续排列的,但每个字符串的实际内容可能分布在内存的不同位置。

内容的提问来源于stack exchange,提问作者0.sh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 03:10:28