In golang, can I print the value of a memory address from a given string?
For example, if run the following code:
a := "A String"
fmt.Println(&a)
It prints 0x1040c108.
How could I take a string such as 0x1040c108 and print the value of that string stored in the memory? Something like fmt.Println(*0x1040c108)
Is this possible?
This can be done, but it is a really really REALLY bad idea. Anytime you are importing the unsafe package, you are either doing something wrong, or something really hardcore. I'm hesitant to even answer this, but here goes.
https://play.golang.org/p/unkb-s8IzAo
package main
import (
"fmt"
"strconv"
"unsafe"
)
func main() {
// original example manually examined the printed address and used the value
// updated to preserve forward compatibility due to runtime changes shifting the address over time
hi := "HI"
// getting address as string dynamically to preserve compatibility
address := fmt.Sprint(&hi)
fmt.Printf("Address of var hi: %s\n", address)
// convert to uintptr
var adr uint64
adr, err := strconv.ParseUint(address, 0, 64)
if err != nil {
panic(err)
}
var ptr uintptr = uintptr(adr)
fmt.Printf("String at address: %s\n", address)
fmt.Printf("Value: %s\n", ptrToString(ptr))
}
func ptrToString(ptr uintptr) string {
p := unsafe.Pointer(ptr)
return *(*string)(p)
}
And yes, this was pretty much taken almost line for line from the unsafe godoc. https://godoc.org/unsafe
Also note that if/when your memory reference is NOT a go string, everything will come crashing down catastrophically. And that go vet is configured to send you an angry message for doing this, reinforcing that this is indeed a bad idea.
UPDATE: Updated example to run on playground as of go 1.15.1, which either the playground or go itself has changed the way the memory is addressed. Or the more likely case that changes in core libs/runtime will shift the address across versions. It now dynamically obtains the address vs a manually hardcoded value.
package main
import "C"
import (
"log"
"strconv"
"unsafe"
)
func main() {
// parse the string into an integer value
addr, _ := strconv.ParseInt("0x1040c108", 0, 64)
// cast the integer to a c string pointer
ptr := (*C.char)(unsafe.Pointer(uintptr(addr)))
// convert to a go string (this will segfault)
str := C.GoString(ptr)
// print it
log.Println(str)
}
Yes!! you can store the address in a pointer variable and print its value by derefrencing it
i := "something"
ptr := &i
fmt.Println(*ptr)
For accessing the memory using a hard coded address such as 0x1040c108, it is necessary for your program to have access to that memory address otherwise, you will get an error saying invalid indirection of a pointer or segmentation fault.
Related
In Golang, the code [body, err := ioutil.ReadAll(resp.Body)], the ioutil.ReadAll() returns a byte Slice array, based on the documentation.
This is stored in the variable 'body'. My question is how to convert this byte Slice array, to an array of Integers.
I just found some code that does what I was wanting:
import "fmt"
import "strconv"
func main() {
var t = []string{"1", "2", "3"}
var t2 = []int{}
for _, i := range t {
j, err := strconv.Atoi(i)
if err != nil {
panic(err)
}
t2 = append(t2, j)
}
fmt.Println(t2)
}
So this code, does do what I want.
BUT l am disappointed in Golang, for not having a nice one liner that could do this
kind of conversion.
Certain basic things like this, should be packaged up for the programmer, and not have to do this kind of 'low' level programming.
Note, i still like Golang, they had done a lot to make a better C type language that has higher level Data Types when compared to C and also make some things more dynamic compared to C.
SO just disappointed they did not make a High Abstraction for this kind of case, which comes up quite a bit.
I've run into an issue in my current project where I have two modules, one implementing an interface for testing purposes, and one just a concrete struct, which each depend on a method from the other.
In order to resolve this tension, I've attempted to create a top-level "container" struct that holds a reference to the dependent struct and interface, and then with a method on the container struct, assign as a member of each component struct that top level container's pointer to the other struct. I am doing this instead of using globals in order to be able to better encapsulate my code for testing purposes.
However, it seems that whichever struct is initialized first does not see the change in the other struct's address when the second struct is initialized. I do not understand why, and I don't seem to be able to make this function as expected.
Since there are many extraneous details in the actual code I've created this toy example to illustrate what I'm talking about.
type container struct {
r requestor
a *A
}
type requestor interface {
Request()
}
type A struct {
r requestor
}
type R struct {
a *A
}
func (r R) Request() {
log.Info("I requested")
return
}
func (container *container) NewA() *A {
log.Info("New A received container.r: ", container.r)
a := &A{
r: container.r,
}
container.a = a
return a
}
func (container *container) NewR() *R {
r := &R{
a: container.a,
}
container.r = r
return r
}
func TestDepResolution(t *testing.T) {
top := container{}
top.NewR()
top.NewA()
// top.a.r = r
log.Infof("top: %+v", top)
log.Infof("R: %+v", top.r)
log.Infof("A: %+v", top.a)
}
It's setup as a test so I can easily execute it within my project. The output is as such:
=== RUN TestDepResolution
INFO[0000] New A received container.r: <nil>
INFO[0000] top: {r:0xc000010028 a:0xc00006abc0}
INFO[0000] R: &{a:0xc00006abc0}
INFO[0000] A: &{r:<nil>}
I expected that A's r variable would become equal to top's r variable after NewR() was called, but it doesn't seem to change. The same issue occurs the other way around if I switch the order of NewA() and NewR().
I expected since I am using pointers and interfaces here that the values would be connected when top's values changed, but it's apparent I must be misunderstanding something. I've tried playing around with the pointers quite a bit to no avail.
So why doesn't this work as I expected? Is there a way to make this work as I've proposed? Or am I thinking about this issue in an entirely wrongheaded way? I have tried to think about extracting functionality from the modules so that they are not mutually dependent and I could avoid this issue entirely, but I have not been able to come up with a good way to do so.
To be able to utilize pointers the way you seem to want to, you first need actual pointers (i.e. not nil pointers) and you also need to use pointer indirection to be able to "share" the updates to the pointed values.
For example:
type T struct { F string }
a := &T{"foo"} // non-nil pointer
b := a
fmt.Println(b) // output: {"foo"}
*a = T{"bar"} // pointer indirection
fmt.Println(b) // output: {"bar"}
For comparison, here's what your code is attempting to do:
type T struct { F string }
a := (*T)(nil) // nil pointer
b := a
fmt.Println(b) // output: <nil>
a = &T{"bar"} // plain assignment
fmt.Println(b) // output: <nil>
And note that even if you used pointer indirection, it is illegal to do so on a nil pointer and the runtime, if it encounters such an operation, will panic.
a := (*T)(nil) // nil pointer
b := a
fmt.Println(b) // output: <nil>
*a = T{"bar"} // pointer indirection on nil, will crash the program
fmt.Println(b)
So, your example doesn't work because it does not properly initialize the pointers and it does not use pointer indirection, rather, it uses simple assignment which just updates the target variable's pointer and not the pointed-to value.
To initialize the container properly you should do it in one step:
func NewContainer() *container {
c := &container{a: &A{}}
c.r = &R{a: c.a}
c.a.r = c.r
return c
}
https://play.golang.com/p/hfbqJEVyAHZ
Or, if you want to do it in two, you can do something like this:
func (c *container) NewA() *A {
log.Println("New A received c.r: ", c.r)
a := &A{
r: c.r,
}
if c.a != nil {
*c.a = *a
} else {
c.a = a
}
return a
}
func (c *container) NewR() *R {
if c.a == nil {
c.a = new(A)
}
r := &R{
a: c.a,
}
c.r = r
c.a.r = r
return r
}
https://play.golang.com/p/krmUQOsACdU
but, as you can see, the multi step approach to initializing so tightly coupled dependencies can get unnecessarily convoluted and ugly, i.e. complex, i.e. very much error prone. Avoid it if you can.
All that said, personally, I would consider this kind of circular dependency a smell and would start thinking about redesign, but maybe that's just me.
My application accepts a pointer from os.Args.
For example
pointer := os.Args[1] //"0x7ffc47e43200"
How can I use that pointer and get the value that is stored on that location?
Disclaimer: As you are probably aware, this is dangerous and if you're going to do this in a production application, you'd better have a really good reason. That being said...
You need to do a few things. Here's the code, and then we'll walk through it.
package main
import (
"fmt"
"os"
"strconv"
"unsafe"
)
func main() {
str := "7ffc47e43200" // strconv.ParseUint doesn't like a "0x" prefix
u, err := strconv.ParseUint(str, 16, 64)
if err != nil {
fmt.Fprintln(os.Stderr, "could not parse pointer:", err)
os.Exit(1)
}
ptr := unsafe.Pointer(uintptr(u)) // generic pointer (like void* in C)
intptr := (*int)(ptr) // typed pointer to int
fmt.Println(*intptr)
}
You can run this on the Go Playground.
First, we need to parse the string as a numerical value. In your example, you gave a hexadecimal number, so we'll parse in base 16 (that's the "16" argument to strconv.ParseUint). Note that strconv.ParseUint doesn't like the "0x" prefix, so I removed it.
Then, we need to convert the number into a pointer type. For this, we will use the unsafe.Pointer type, which is special to the Go compiler. Normally, the compiler won't let you convert between pointer types. The exception is that, according to the unsafe.Pointer documentation:
A pointer value of any type can be converted to a Pointer.
A Pointer can be converted to a pointer value of any type.
A uintptr can be converted to a Pointer.
A Pointer can be converted to a uintptr.
Thus, in order to convert to a pointer, we'll need to first convert to a uintptr and then to an unsafe.Pointer. From here, we can convert to any pointer type we want. In this example, we will convert to an int pointer, but we could choose any other pointer type as well. We then dereference the pointer (which panics in this case).
We have written one program by which we try to find an address of a constant. Is it possible to do it like that?
package main
func main() {
const k = 5
address := &k
}
It gives an error, can anyone tell how can we find the address of a constant?
In short: you can't.
The error message says:
cannot take the address of k
There are limitations on the operand of the address operator &. Spec: Address operators:
For an operand x of type T, the address operation &x generates a pointer of type *T to x. The operand must be addressable, that is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. As an exception to the addressability requirement, x may also be a (possibly parenthesized) composite literal. If the evaluation of x would cause a run-time panic, then the evaluation of &x does too.
Constants are not listed as addressable, and things that are not listed in the spec as addressable (quoted above) cannot be the operand of the address operator & (you can't take the address of them).
It is not allowed to take the address of a constant. This is for 2 reasons:
A constant may not have an address at all.
And even if a constant value is stored in memory at runtime, this is to help the runtime to keep constants that: constant. If you could take the address of a constant value, you could assign the address (pointer) to a variable and you could change that (the pointed value, the value of the constant). Robert Griesemer (one of Go's authors) wrote why it's not allowed to take a string literal's address: "If you could take the address of a string constant, you could call a function [that assigns to the pointed value resulting in] possibly strange effects - you certainly wouldn't want the literal string constant to change." (source)
If you need a pointer to a value being equal to that constant, assign it to a variable of which is addressable so you can take its address, e.g.
func main() {
const k = 5
v := k
address := &v // This is allowed
}
But know that in Go numeric constants represent values of arbitrary precision and do not overflow. When you assign the value of a constant to a variable, it may not be possible (e.g. the constant may be greater than the max value of the variable's type you're assigning it to - resulting in compile-time error), or it may not be the same (e.g. in case of floating point constants, it may lose precision).
I often hit this problem when creating large, nested JSON objects during unit tests. I might have a structure where all the fields are pointers to strings/ints:
type Obj struct {
Prop1 *string
Prop2 *int
Status *string
}
and want to write something like:
obj := Obj{
Prop1: &"a string property",
Prop2: &5,
Status: &statuses.Awesome,
}
When I initialise it, but the language doesn't allow this directly. A quick way to bypass this is to define a function that takes a constant and returns its address:
s := func(s string) *string { return &s }
i := func(i int) *int { return &i }
obj := Obj{
Prop1: s("a string property"),
Prop2: i(5),
Status: s(statuses.Awesome)
}
This works due to the fact that when the constant is passed as a parameter to the function, a copy of the constant is made which means the pointer created in the function does not point to the address of the constant, but to the address of its copy, in the same way as when a constant value is assigned to a var. However, using a function to do this makes it more readable/less cumbersome IMO than having to forward declare large blocks of variables.
The AWS SDK uses this technique. I now find myself regularly adding a package to my projects that looks something like:
package ref
import "time"
func Bool(i bool) *bool {
return &i
}
func Int(i int) *int {
return &i
}
func Int64(i int64) *int64 {
return &i
}
func String(i string) *string {
return &i
}
func Duration(i time.Duration) *time.Duration {
return &i
}
func Strings(ss []string) []*string {
r := make([]*string, len(ss))
for i := range ss {
r[i] = &ss[i]
}
return r
}
Which I call in the following way:
func (t: Target) assignString(to string, value string) {
if to == tags.AuthorityId {
t.authorityId = ref.String(value)
}
// ...
}
You can also add a deref package, though I have generally found this to be less useful:
package deref
func String(s *string, d string) string {
if s != nil { return *s }
return d
}
// more derefs here.
EDIT April 2022:
With the release of go 1.18, it's now possible to define a single method to handle all conversions from constants into pointers:
package ref
func Of[E any](e E) *E {
return &e
}
I found another way to deal with this, which is using AWS API:
import "github.com/aws/aws-sdk-go/aws"
type Obj struct {
*int
}
x := aws.Int(16) // return address
obj := Obj{x} // work fine
this method is literally same as the answer above, but you dont have to write the whole functions on your own.
See: https://docs.aws.amazon.com/sdk-for-go/api/aws/
These 3 options could be helpful:
Using a helper function with generics. (Works for both primitive and custom types)
package main
import "fmt"
type Role string
const (
Engineer Role = "ENGINEER"
Architect Role = "ARCHITECT"
)
const (
EngineerStr string = "ENGINEER"
ArchitectStr string = "ARCHITECT"
)
func main() {
fmt.Println(PointerTo(Engineer)) // works for custom types
fmt.Println(PointerTo(EngineerStr)) // works for primitive types
}
func PointerTo[T any](v T) *T {
return &v
}
Try it on playground
Using pointy. (Works only for primitive types)
Using a ToPointer() method. (Works only for custom types)
package main
import "fmt"
type Role string
const (
Engineer Role = "ENGINEER"
Architect Role = "ARCHITECT"
)
func (r Role) ToPointer() *Role {
return &r
}
func main() {
fmt.Println(Engineer.ToPointer())
}
Try it on playground
What the constants section does not make very clear: Constants are, unlike variables, not present in the compiled code or running program. They are untyped and will only be in memory once they are assigned to a variable.
As a result, they seem1 to have infinite precision. If you look at this example, you can see that I can assign the constant to a variable without casting it, and the variable will hold as much of the constants precision as it can.
1 As the spec also points out, integers have at least 256 bits, floats at least 256 bits mantissa and 32 bits exponent, and the compiler will throw an error if its internal constructs cannot accurately store a constant.
I understand that Go doesn't have any constructors and a New func is used in its place, but according to this example.
func NewFile(fd int, name string) *File {
if fd < 0 {
return nil
}
f := File{fd, name, nil, 0}
return &f
}
They always return &f. Why just simply returning File isn't suffice?
Update
I've tried returning the created object for a simple struct and it's fine. So, I wonder if returning an address is a standard way of constructor or something.
Thanks.
As mentioned, yes, the spec allows you to return either values (as non-pointers) or pointers. It's just a decision you have to make.
When to return pointer?
Usually if the value you return is "more useful" as a pointer. When is it more useful?
For example if it has many methods with pointer receiver. Yes, you could store the return value in a variable and so it will be addressable and you can still call its methods that have pointer receivers. But if a pointer is returned right away, you can "chain" method calls. See this example:
type My int
func (m *My) Str() string { return strconv.Itoa(int(*m)) }
func createMy(i int) My { return My(i) }
Now writing:
fmt.Println(createMy(12).Str())
Will result in error: cannot call pointer method on createMy(12)
But if works if you return a pointer:
func createMy(i int) *My { return (*My)(&i) }
Also if you store the returned value in a data structure which is not addressable (map for example), you cannot call methods on values by indexing a map because values of a map are not addressable.
See this example: My.Str() has pointer receiver. So if you try to do this:
m := map[int]My{0: My(12)}
m[0].Str() // Error!
You can't because "cannot take the address of m[0]". But the following works:
m := map[int]*My{}
my := My(12)
m[0] = &my // Store a pointer in the map
m[0].Str() // You can call it, no need to take the address of m[0]
// as it is already a pointer
And another example for pointers being useful is if it is a "big" struct which will be passed around a lot. http.Request is a shining example. It is big, it is usually passed around a lot to other handlers, and it has methods with pointer receiver.
If you return a pointer, that usually suggests that the returned value is better if stored and passed around as a pointer.
Pointer receiver accepts both pointer and value types, as long as it matches the data type.
type User struct {
name string
email string
age int
}
// NewUserV returns value ... ideally for a User we should not be
// returning value
func NewUserV(name, email string, age int) User {
return User{name, email, age}
}
// NewUserP returns pointer ...
func NewUserP(name, email string, age int) *User {
return &User{name, email, age}
}
// ChangeEmail ...
func (u *User) ChangeEmail(newEmail string) {
u.email = newEmail
}
func main() {
// with value type
usr1 := NewUserV("frank", "frank#camero.com", 22)
fmt.Println("Before change: ", usr1)
usr1.ChangeEmail("frank#gmail.com")
fmt.Println("After change: ", usr1)
// with pointer type
usr2 := NewUserP("john", "john#liliput.com", 22)
fmt.Println("Before change: ", usr2)
usr2.ChangeEmail("john#macabre.com")
fmt.Println("After change: ", usr2)
}
In addition to what icza mentioned about the big struct being passed around. Pointer values are a way of saying that pointer semantics are at play and who ever uses the particular type should not make copy of the value which is being shared by the pointer.
If you look at the struct of File or http type, it maintains channels or some other pointer types which is unique to that value. Make a copy of the value (given to you by the pointer) would lead to hard to find bugs since the copied value might end up writing or reading to the pointer types of the original value.