0

I am trying to understand how go represents slice of strings in memory (They are not aligned in close proximity to each other). First of all, looking at this C code

#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]);
}

Output on my computer:

0x1068d0fa0
0x1068d0fa3
0x1068d0fa7
0x1068d0fa0 -> h
0x1068d0fa1 -> i
0x1068d0fa2 -> '\0'
0x1068d0fa3 -> f
0x1068d0fa4 -> ... till the last character in x[2] they all have a byte difference

But in golang, it is not clear to me how this work,

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])
}

Output on my computer:

0x430050
0x430060
0x430070
0x430080

They all have 10-byte difference, how does go represent this in memory?

0.sh
  • 2,659
  • 16
  • 37

1 Answers1

-1

Actually, there is a 16 byte difference (since the addresses are in hex), which would correspond to the slice layout described in here, that is:

  • Data pointer (8 bytes)
  • Length (int, 4 bytes)
  • Capacity (int, 4 bytes)
Mikdore
  • 699
  • 5
  • 16
  • Does this mean that go only supports strings of length less than 4,294,967,296 characters? – Woody1193 Nov 10 '22 at 01:45
  • 1
    @Woody1193 half of that since `int` is signed. In theory, if your architecture's int is bigger than 32 bits, then you could have bigger slices, see here https://stackoverflow.com/questions/27647737/maximum-length-of-a-slice-in-go – Mikdore Nov 10 '22 at 01:50
  • Thanks, I don't think I'll ever need that much space but it's nice to know it exists. – Woody1193 Nov 10 '22 at 02:01
  • 3
    You can treat strings as a read-only slice of bytes for most purposes, but strings don't have a capacity. See [the Go Blog](https://go.dev/blog/slices#strings) for more info. – Charlie Tumahai Nov 10 '22 at 02:21
  • 2
    The [string header](https://pkg.go.dev/reflect#StringHeader) and [slice header](https://pkg.go.dev/reflect#SliceHeader) are not the same. Also, `int` and `uintptr` will generally be the same size. – Hymns For Disco Nov 10 '22 at 03:07