package main
import (
"fmt"
"unsafe"
"runtime"
)
func getPoi() unsafe.Pointer {
var a = []int{1, 2, 3}
return unsafe.Pointer(&a[0])
}
func main() {
p := getPoi()
runtime.GC()
fmt.Println("Hello, playground %v
", *(*int)(unsafe.Pointer(uintptr(p)+8)))
}
output: 3
https://play.golang.org/p/-OQl7KeL9a
Just examining abilities of unsafe pointers, trying to minimize memory overhead of slice structure (12 byte)
I wonder if this example correct or not. And if not, what will go wrong exactly after such actions. if it's not correct, why the value is still available even after an explicit call to GC ? Is there any aproach to reach minimum overhead on storage like 'slice of slices', as it would be in C (just array of pointers to allocated arrays, when overhead on each row is sizeof(int*)).
It's possible, that by coincidence, this will work out for you but I would regard it as unsafe and unsupported. The problem is, if the slice grows beyond it's capacity and needs to be reallocated, what happens to your pointer? Really if you want to optimize performance, you should be using an array. On top of it's performance being inherently better and it's memory footprint being smaller, this operation would always be safe.
Also, just generally speaking I see people doing all kinds of stupid things to try and improve performance when their design is inherently poor (like using dynamic arrays or linked lists for no reason). If you need the dynamic growth of a slice then an array isn't really an option (and using that pointer is also most likely unsafe) but in many cases developers just fail to size their collection appropriately out of idk, laziness? I assume your example is contrived but in such a scenario you have no reason to ever use a slice since your collections size is known at compile time. Even if it weren't, often times the size can be determined during runtime in advance of the allocation and people just fail to do it for the convenience of using abstracted dynamically sized collections.