Search code examples
gomemory-managementmemory-layout

Why is go often storing the data of strings at misaligned addresses


I've read a lot about how important alignment of values in memory is, because accessing unaligned addresses may either slow down the operation or plainly not work at all depending on the CPU architecture (one reference https://syslog.ravelin.com/go-and-memory-layout-6ef30c730d51). But then I noticed that when instantiating a simple string in Go, it often stores the string value at a misaligned address.

This can be seen by running this code:

package main

import (
    "fmt"
    "unsafe"
    "reflect"
)

func main() {
    testString:= "testString"

    fmt.Println(fmt.Sprintf("Data is at address %d", ((*reflect.StringHeader)(unsafe.Pointer(&testString))).Data))
}

When running it on https://play.golang.org/p/d1eX0nP3AgV I keep getting:

Data is at address 1140305

1140305 is clearly not divisible by 4 or 8.

Could somebody explain why Go is storing that value at a misaligned address please? Wouldn't it be better to use an aligned one? Is that simply to not waste space, while relying on the fact that modern CPUs can handle it. Or is that because virtual memory layer abstracts the physical memory address and actually the physical address is properly aligned?


Solution

  • You are right a 32-bit value (such as an integer) should be aligned on a 4-byte boundary, otherwise accessing it may require two memory accesses instead of one. Similarly a 64-bit value should be aligned on an 8-byte boundary, though in a 32-bit system (ie 32 data lines to memory) a 4-byte boundary is adequate as two memory accesses are required anyway.

    However, the data of a string in Go is effectively an array of bytes and hence has no alignment requirements. You will find the same thing if you print the address of a string in C (which cares a lot about alignment for efficiency reasons).

    Alignment is fairly straightforward once you understand it but takes a lot of explaining. I wrote about it (for C) at http://devmethodologies.blogspot.com/2013/04/alignment-and-pragma-pack.html.