Go pointer subtraction [closed] - go

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
When I run this program it looks like the value of the two pointers is 16 bytes (x’10”) bytes apart but how can that be if the first string is over 16 bytes long? Or am I looking at this incorrectly?
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println("Hello, playground")
x := "string 4"
xx := "string2"
y := "string3"
xptr := &x
fmt.Println(xptr)
fmt.Println(*xptr)
xxptr := &xx
fmt.Println(xxptr)
fmt.Println(*xxptr)
fmt.Println("hey")
fmt.Println("hey")
fmt.Println("hey")
fmt.Println("hhey")
fmt.Println("hey")
yptr := &y
fmt.Println(yptr, *yptr)
xxx := math.Pow(2,3)
fmt.Printf("%.6f",xxx)
}

The program prints the addresses of the string variables, not the address of the array of bytes backing the strings. A string variable contains a pointer to the string data and the string length. The structure of a string variable is reflected in the reflect.StringHeader type:
type StringHeader struct {
Data uintptr
Len int
}
See Go Data Structures for a detailed description of the string memory layout in Go.
On a 64-bit architecture, the size of a string variable is 16 bytes.
Use the unsafe package to extract the pointer to the string data:
xh := (*reflect.StringHeader)(unsafe.Pointer(&x))
xxh := (*reflect.StringHeader)(unsafe.Pointer(&xx))
fmt.Printf("0x%x %d\n", xh.Data, xh.Len) // prints 0x4c0648 26
fmt.Printf("0x%x %d\n", xxh.Data, xxh.Len) // prints 0x4bcfd4 7

Related

strconv.ParseInt: parsing "18446744073709551615": value out of range [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
Is it a normal behavior when parsing uint64 max value with strconv.ParseInt?
i, err := strconv.ParseInt("18446744073709551615", 10, 64)
fmt.Println(i, err)
I got an error: "strconv.ParseInt: parsing "18446744073709551615": value out of range", when maximum allowed value for uint64 is: 18446744073709551615
Can you explain such behavior?
https://golang.org/src/builtin/builtin.go?s=1026:1044#L26
Call ParseUint to parse an unsigned integer.
The ParseInt function parses signed integers. The maximum signed integer is 9223372036854775807.
Based the comments ,I reproduced your code as follows:
package main
import (
"fmt"
"strconv"
)
func main() {
i, err := strconv.ParseUint("18446744073709551615", 10, 64)
fmt.Println(i, err)
}
Output:
18446744073709551615 <nil>

How does Go allocate memory when using new(string) [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
Consider the following code:
str := new(string)
p := str
fmt.Printf("Current value = %v %p\n", *str, str)
*str = "abc"
fmt.Printf("New value = %v %p\n", *str, str)
fmt.Printf("Current value = %v %p\n", *p, p)
In the second line, p := str both pointers point to the same location, the memory address where new(string) allocated the default value of a string, an empty string. I would have expected *str = "abc" to be a problematic assignment (in c for example, this could overwrite memory). But not only does this work and p take on the same value, it also seems to continue to work if I set *str to be some very large string.
I would expect that str is pointing to a location that has a fixed number of bytes allocated to it. For a default string value, that seems to be 16 bytes. How does golang allow the assignment of some arbitrarily sized string to the location of a pointer?
In the second line, p := str both pointers point to the same location, the memory address where new(string) allocated the default value of a string, an empty string.
Correct
I would have expected *str = "abc" to be a problematic assignment (in c for example, this could overwrite memory). But not only does this work and p take on the same value, it also seems to continue to work if I set *str to be some very large string.
Your expectation is just plain wrong. Go is not C and strings are represented differently in Go than in C.
I would expect that str is pointing to a location that has a fixed number of bytes allocated to it.
Thats true. Any type has some defined fixed size. This is a feature of Go.
For a default string value, that seems to be 16 bytes.
No. 1. This the size of the string variable is not dependent on the string content (also see above). 2. This is platform dependent. 3. Yes 16 bytes = 2 words on 64bit systems.
How does golang allow the assignment of some arbitrarily sized string to the location of a pointer?
A variable of type string doesn't hold the actual string content, it is just a 2 word descriptor, roughly (length, pointer-to-actual-content). *str = "abc" doesn't store "abc" in the string variable: It stores "abc" somewhere and make the pointer-to-actual-content point there. The type string in Go is not what a char* is in C.

Cannot use _ as value [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I saw a piece of code used to print values passed in arguments:
package main
import "fmt"
import "os"
func main() {
for _, val := range os.Args[1:] {
fmt.Printf("%d %s \n", _ , val)
}
}
Original program had a note that _ holds index but was not printing it. When I tried to print index, I am getting below error:
./main.go:8:16: cannot use _ as value
What is the issue here?
_(underscore) in Golang is known as the Blank Identifier and it's value can't be used(it kind of doesn't hold any value).
Go doesn't allow you to have a unused variable therefore, original program used _ to drop the value and compile the program successfully. Use i instead of _ and run the program.
package main
import "fmt"
import "os"
func main() {
for i, val := range os.Args[1:] {
fmt.Printf("%d %s \n", i , val)
}
}

running into invalid memory address when attempting to assign values in golang to a slice of type pointer [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I'm bit lost with this panic when writing gRPC server in Go
panic: runtime error: invalid memory address or nil pointer dereference [recovered]
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xc0000005 code=0x1 addr=0x18 pc=0x8c7892]
Here's what I am trying to do, attempting to create a slice of test data :
inputVal := make([]*pb.TableHeader, 1)
for i := range inputVal {
inputVal[i].UserDefinedAlias = "myCustomName"
inputVal[i].Type = "SomeType"
inputVal[i].Class = "TestClass"
inputVal[i].ColumnID = "Col12"
inputVal[i].IsSortable = false
inputVal = append(inputVal, inputVal[i])
}
TableHeader has this structure
type TableHeader struct {
ColumnID string `protobuf:"bytes,1,opt,name=columnID,proto3" json:"columnID,omitempty"`
UserDefinedAlias string `protobuf:"bytes,2,opt,name=userDefinedAlias,proto3" json:"userDefinedAlias,omitempty"`
IsSortable bool `protobuf:"varint,3,opt,name=isSortable,proto3" json:"isSortable,omitempty"`
Type string `protobuf:"bytes,4,opt,name=type,proto3" json:"type,omitempty"`
Class string `protobuf:"bytes,5,opt,name=class,proto3" json:"class,omitempty"`
XXX_NoUnkeyedLiteral struct{} `json:"-"`
XXX_unrecognized []byte `json:"-"`
XXX_sizecache int32 `json:"-"`
}
And trying to process that test data created above using following in an rpc service
inputForProcessing := make([]*dt.TableHeader, len(inputVal))
log.Println("reached here for actual processing ",len(inputForProcessing))
for i, v := range inputVal {
inputForProcessing[i].ColumnID = v.ColumnID
inputForProcessing[i].Class = v.Class
inputForProcessing[i].Type = v.Type
inputForProcessing[i].IsSortable = v.IsSortable
inputForProcessing[i].UserDefinedAlias = v.UserDefinedAlias
inputForProcessing = append(inputForProcessing, inputForProcessing[i])
}
When you call inputVal := make([]*pb.TableHeader, 1), this creates a slice of *pb.TableHeader of size one, but does nothing to initialize that one element. If you print it out, you'll get: [<nil>].
This means that the first (and only) iteration in for i := range inputVal will be with i == 0 and inputVal[i] will be nil. Attempting to set a field on a nil pointer causes the panic you see.
The same goes for inputForProcessing, all elements in the created slice will be nil.
Furthermore, you seem to be trying to append inputVal[i] to inputVal. The given element is already there.
Instead, you probably want something along the lines of:
inputVal := make([]*pb.TableHeader, 1)
for i := range inputVal {
inputVal[i] = &pb.TableHeader{
UserDefinedAlias: "myCustomName",
Type: "SomeType",
etc...
}
}

Go newbie: Getting "mismatched types *int and int" error when trying to compare reference to static integer [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I'm learning Go and trying to use reference to integer value in if-clause.
package main
import (
"fmt"
)
func main() {
a := 19
b := &a
if b > 10 {
fmt.Println("Its bigger")
}
}
This gives error message for type mismath.
How could I successfully compare value which b is referencing. In my training code I'm reading command line arguments with flags, but I suppose this example is reprex.
How should I compare when havin only reference available?
Here b is a pointer of int means *int. You can't compare *int type with int type.
Use *b to dereference to get the value and then compare with constant value.
if *b > 10 {
fmt.Println("Its bigger")
}

Resources