I've a question to the Go programmers amongst you. I can't find information about the details of the memory model of Go. I shall try to describe my problem:
If I declare and define a variable or array in C, I know that this exists somewhere in the RAM at exactly one position with one specific address, until I do something that will change this.
This is not the case in Python: Python does the whole memory management for me, I can't be sure that my data will be located always at one position. E.g. strings are in practice immutable, even though the language suggests that they is not. This makes secure programming with sensitive data nearly impossible (or at least very impractical).
My question is: How does Go work from this perspective. Is it more like C or like Python? Or is it completely different? Is it possible to handle sensitive data as comfortably as in C?
Note: as mention in "Go Slices: usage and internals":
The in-memory representation of
[4]int
is just four integer values laid out sequentially:
Go's arrays are values.
An array variable denotes the entire array; it is not a pointer to the first array element (as would be the case in C). This means that when you assign or pass around an array value you will make a copy of its contents.
(To avoid the copy you could pass a pointer to the array, but then that's a pointer to an array, not an array.)One way to think about arrays is as a sort of struct but with indexed rather than named fields: a fixed-size composite value.
If you are looking at "a pointer to an array", then you would need a slice.
A slice is a descriptor of an array segment. It consists of a pointer to the array, the length of the segment, and its capacity (the maximum length of the segment).
Our variable
s
, created earlier bymake([]byte, 5)
, is structured like this:
For the way memory allocation work for array and slice, you can check out "Effective Go"
Go has two allocation primitives, the built-in functions
new
andmake
.
They do different things and apply to different types, which can be confusing, but the rules are simple.
Let's talk about new first. It's a built-in function that allocates memory, but unlike its namesakes in some other languages it does not initialize the memory, it only zeros it.
That is,new(T)
allocates zeroed storage for a new item of typeT
and returns its address, a value of type*T
.
In Go terminology, it returns a pointer to a newly allocated zero value of typeT
.allocation with
make
: The built-in functionmake(T, args)
serves a purpose different fromnew(T)
. It creates slices, maps, and channels only, and it returns an initialized (not zeroed) value of typeT
(not*T
).
The reason for the distinction is that these three types represent, under the covers, references to data structures that must be initialized before use.
A slice, for example, is a three-item descriptor containing a pointer to the data (inside an array), the length, and the capacity, and until those items are initialized, the slice is nil.
See more at "Understanding Pointers and Memory Allocation".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With