Golang Unsafe Type Conversions and Memory Access

Caution! You must steer clear of the usage of unsafe to your programs, except you 100% certain what you might be doing. It is known as unsafe for a explanation why.

Cross is a strongly typed, you need to convert variable from one sort to every other to make use of in numerous portions of application. However every so often you want to step round this sort protection. It may well be had to optimization of bottle necks in prime load methods, the place each tick counts. Unsafe operation doubtlessly may protected a large number of allocations. Unsafe additionally permits to hack into any struct box, together with slices, strings, maps and so forth.

Exchange string instance

String are immutable in Cross. If you wish to trade a string, typically you need to allocate a brand new one. Let’s hack Cross a bit bit with unsafe bundle, and in reality trade the string!

bundle primary import ( "fmt" "mirror" "time" "unsafe"
) func primary()  a := "Hi. Present time is " + time.Now().String() fmt.Println(a) stringHeader := (*mirror.StringHeader)(unsafe.Pointer(&a)) *(*byte)(unsafe.Pointer(stringHeader.Information + 5)) = '!' fmt.Println(a)


Hi. Present time is 2020-03-14 21:40:38.36328248 +0300 +03 m=+0.000037994
Hi! Present time is 2020-03-14 21:40:38.36328248 +0300 +03 m=+0.000037994

String is modified!

What is going on on this code? Following steps:

  1. Convert a string pointer to

    . Any pointer may well be transformed to


    and vise versa.


    additionally may well be transformed to


    – deal with in integer shape.

  2. Convert



    pointer, to get Information pointer.


    sort displays string inside runtime struct. Beneath the hood string is represented via duration price and


    pointer to reminiscence with the knowledge.

  3. Transfer the pointer 5 bytes ahead. With

    it’s conceivable to do pointer mathematics.

  4. Convert new



    , and subsequent to


    pointer. This byte is in reality a part of a string.

  5. Assign new price to byte via pointer. String is modified!
Through the best way, following code will produce segmentation violation error. Cross compiler understands that string is continuous and put it in reminiscence in conjunction with different constants, the place adjustments are forbidden. That is why I used


within the first instance.

bundle primary import ( "fmt" "mirror" "unsafe"
) func primary() 


Hi. Have a pleasant day!
sudden fault deal with 0x4c3e31
deadly error: fault
[signal SIGSEGV: segmentation violation code=0x2 addr=0x4c3e31 pc=0x48cf33]

Package deal unsafe

func Alignof(x ArbitraryType) uintptr
func Offsetof(x ArbitraryType) uintptr
func Sizeof(x ArbitraryType) uintptr
sort Pointer *ArbitraryType sort ArbitraryType
// represents the kind of an arbitrary Cross expression,
// now not in reality a part of a bundle

provides offset of box in struct.


is a measurement of variable in reminiscence, referenced reminiscence now not integrated.


provides data in regards to the alignment of variable deal with.

Some examples of the usage of





  1. Unsafe array iteration and sort conversion at the fly with 0 allocations.
  2. Getting details about the real measurement of structs in reminiscence.
  3. Converting struct box without delay in reminiscence, with struct pointer and box offset.
bundle primary import ( "fmt" "unsafe"
) sort Bytes400 struct  sort TestStruct struct  a [9]int64 b byte c *Bytes400 d int64
 func primary()  array := [10]uint641, 2, 3, 4, 5, 6, 7, 8, 9, 10 var sum int8 // Unsafe array iteration sizeOfUint64 := unsafe.Sizeof(array[0]) for i := uintptr(0); i < 10; i++  fmt.Println(sum) // Measurement of struct and offsets of struct fields t := TestStructb: 42 fmt.Println(unsafe.Sizeof(t)) fmt.Println(unsafe.Offsetof(t.a), unsafe.Offsetof(t.b), unsafe.Offsetof(t.c), unsafe.Offsetof(t.d)) fmt.Println(unsafe.Sizeof(Bytes400)) // Exchange struct box t.b price *(*byte)(unsafe.Pointer(uintptr(unsafe.Pointer(&t)) + unsafe.Offsetof(t.b)))++ fmt.Println(t.b)


0 72 76 80

Pointer mathematics and rubbish collector



may also be transformed to a


and vise versa. Most effective option to carry out pointer mathematics is with utilization of


. Common rule is that


is an integer price with out pointer semantics. It isn’t protected to make use of


as an best pointer to object. Rubbish collector blind to it and object reminiscence may well be reused. It’s best to transform it again to


immediately, after mathematics operations are carried out.

Benchmarks of unsafe string to []byte conversion

bundle primary import ( "mirror" "unsafe"
) func SafeBytesToString(bytes []byte) string  go back string(bytes)
 func SafeStringToBytes(s string) []byte  go back []byte(s)
 func UnsafeBytesToString(bytes []byte) string  func UnsafeStringToBytes(s string) []byte 

pass take a look at -bench=.

Benchmark effects:

BenchmarkSafeBytesToString-8 257141380 4.50 ns/op
BenchmarkSafeStringToBytes-8 227980887 5.38 ns/op
BenchmarkUnsafeBytesToString-8 1000000000 0.305 ns/op
BenchmarkUnsafeStringToBytes-8 1000000000 0.274 ns/op

Unsafe conversion is greater than 10 occasions sooner! However this conversion best allocates new header, knowledge stays the similar. So for those who trade slice after conversion, string can even trade. The next take a look at will go:

func TestUnsafeBytesToString(t *checking out.T)  bs := []byte("Take a look at") str := UnsafeBytesToString(bs) if str != "Take a look at"  // Take a look at string mutation bs[0] = 't' if str != "take a look at" 

Should you in reality want to accelerate conversions or hack inside of pass buildings – use unsafe bundle. In different circumstances attempt to steer clear of it, it isn’t exhausting to debris one thing up with it.

Thank you for studying and have a pleasant protected day!