Common mistakes with pointers in Go [closed] - pointers

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
I haven't used pointers in a long time, and when I did it was only in an academic setting and I am a bit rusty now thanks to C#/Java/scala.
What are some common mistakes people make with pointers in Golang?
Are there ways of testing if you have used them correctly? I guess it is always hard to detect a memory leak until things go wrong.

Given that Go is garbage collected and doesn't allow pointer arithmetics there is not much that you can do wrong. You can use unsafe package for that but it's name speaks for itself - it's unsafe.
nil pointers are still there. Dereferencing them will cause a panic which is somewhat like exceptions in C#/Java - you get a clear error description and a stack trace where it happend.
Memory leaks - GC will do almost everything for you just like in C#/Java. But there is a special case that I know of - slices. Removing an element is usually done by creating another slice like this:
a = append(a[:i], a[i+1:]...)
this code might leak the element you removed. That's because internally slice is a struct that contains an array (just a pointer), length and capacity. When you remove an element new slice might contain the same array and it will still reference the element you removed. GC will not free it. To solve that you need to nil the element before removing it.
And there is also pointer vs value method receivers confusion. It's not a mistake, more like a design decision you have to make and understand. Method with value receiver will get a copy of the receiver, it can't modify the state. So if you want to modify the state then you need pointer receiver. Also if your structs are big and you don't want them to be copied every time you call a methid you also might want to use pointer receivers.

The common mistake I found is that people forget about pointers inside their complicated structs.
Each slice, map, interface is a pointer. When you have a struct containing another struct containing a pointer, you might just see S1{s2: S2}, and you think it's fine to have a struct copied like this: a=b, when actually it's not fine, as inside s2, a poiner vatriable, let's say p, will have their address copied, and not the value to which it points. When yoy modify the value found at *a.s2.p, the *b.s2.p will return the same value.
package main
import (
"fmt"
)
type S1 struct {
v int
s2 S2
}
type S2 struct {
p *int
}
func main() {
x := 1
b := S1{v: 10, s2: S2{p: &x}}
a := b
fmt.Printf("a = %+v\nb = %+v\n*a.s2.p = %d\n*b.s2.p = %d\na.s2.p = %p\nb.s2.p = %p\n", a, b, *a.s2.p, *b.s2.p, a.s2.p, b.s2.p)
*a.s2.p = 5
fmt.Printf("*a.s2.p = %d\n*b.s2.p = %d\na.s2.p = %p\nb.s2.p = %p\n", *a.s2.p, *b.s2.p, a.s2.p, b.s2.p)
}
http://play.golang.org/p/KQ99KICgbu
This it's a very simple example, and it looks obvious there is an issue, but on bigger applications this might not be that obvious.
This issue appears with channels as well. If you send a pointer, you will get on the other end the same pointer (a copy of your pointer's value, which is an address). In this case, as with the first case, a safe solution is to use a Clone function, to create a cloned object. You send the clone through your channel and don't use it anymore on the sender side.

Related

Why does cloning an Rc pointer in Rust increase its strong_count?

I have this function:
use std::rc::Rc;
fn rc_counter() -> Rc<String> {
let p1 = Rc::new(String::from("Hello"));
println!("count {}", Rc::strong_count(&p1)); // 1
// this is an owned type not a reference
let p2 = p1.clone();
println!(
"Count after the clone is created for the pointer {}",
Rc::strong_count(&p1)
); // 2
p2
}
I created p1 pointer. Print its strong count as 1
then I cloned it and checked the strong count of "p1" and it prints out 2.
As far as I know, cloning means, replicating the pointer in stack and replicating the data in the heap. But looks like cloned p2 is still related to the p1. How is this possible?
That's the whole point of Rc - Rc is a reference counting smart pointer for shared ownership. It makes it possible that multiple owners own it simultaneously.
To not break Rust's ownership rules, all of the owners can only access it immutably, though.
For that reason, .clone() is kind of discouraged, because it doesn't make it clearly readable whether it clones the Rc or the inner object.
In your case, p1.clone() is equivalent to Rc::clone(&p1).
If you want to clone the inner String, you need to do String::clone(&p1), or (*p1).clone().
As far as I know, cloning means, replicating the pointer in stack and replicating the data in the heap. But looks like cloned p2 is still related to the p1.
You are describing the behavior of Box. If you want non-shared ownership of an object on the heap, and if you clone it it also clones the object on the heap, use Box instead of Rc. The two are very similar apart of the fact that Rc is for shared ownership.

invalid memory address or nil pointer dereference after first loop iteration [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
When I return (A map slice) from GetCompanyFilingListRes and print the output my code runs fine for one iteration. But on the second iteration I get a panic: runtime error: invalid memory address or nil pointer dereference.
package main
import (
"data/edgar"
"fmt"
"net/http"
)
func main() {
url := "calltomylocalserver.com/page.html"
res, _ := http.Get(url)
for i := 0; i < 100000; i++ {
// GetCompanyFilingListRes comsumes res.Body
// before returning a slice of maps
m := edgar.GetCompanyFilingListRes(res)
fmt.Println(m)
}
}
I'm sure this is something quite simple I'm missing but I don't why res doesn't seem to be accessible after the first iteration. Is the GC removing it from memory? How would I stop this happening? Thanks.
Edit:
I think my mistake with this question was not including the fact that GetCompanyFilingListRes consumes the res.Body. And as leaf bebop mentioned it can only be consumed once.
There's a related answer I found here.
It seems very likely to be because res is a Response and Response.Body is a ReadCloser which can only be consumed once.
If you want to re-use the body, read it into a buffer (like []byte or a string) using ioutil.ReadAll. If you want extra data from res, use a struct to wrap it.
If your use case auctually use different responses (which make more sense to me), move the http.Get into the loop. (Warning: fetch an url 1e5 times can cause trouble).

Why is fmt.Println not consistent when printing pointers?

I'm an experienced programmer but have never before touched Go in my life.
I just started playing around with it and I found that fmt.Println() will actually print the values of pointers prefixed by &, which is neat.
However, it doesn't do this with all types. I'm pretty sure it is because the types it does not work with are primitives (or at least, Java would call them that, does Go?).
Does anyone know why this inconsistent behaviour exists in the Go fmt library? I can easily retrieve the value by using *p, but for some reason Println doesn't do this.
Example:
package main
import "fmt"
type X struct {
S string
}
func main() {
x := X{"Hello World"}
fmt.Println(&x) // &{Hello World} <-- displays the pointed-to value prefixed with &
fmt.Println(*(&x)) // {Hello World}
i := int(1)
fmt.Println(&i) // 0x10410028 <-- instead of &1 ?
fmt.Println(*(&i)) // 1
}
The "technical" answer to your question can be found here:
https://golang.org/src/fmt/print.go?#L839
As you can see, when printing pointers to Array, Slice, Struct or Map types, the special rule of printing "&" + value applies, but in all other cases the address is printed.
As for why they decided to only apply the rule for those, it seems the authors considered that for "compound" objects you'd be interested in always seeing the values (even when using a pointer), but for other simple values this was not the case.
You can see that reasoning here, where they added the rule for the Map type which was not there before:
https://github.com/golang/go/commit/a0c5adc35cbfe071786b6115d63abc7ad90578a9#diff-ebda2980233a5fb8194307ce437dd60a
I would guess this had to do with the fact that it is very common to use for example pointers to Struct to pass them around (so many times you'd just forget to de-reference the pointer when wanting to print the value), but no so common to use pointers to int or string to pass those around (so if you were printing the pointer you were probably interested in seeing the actual address).

cgo pointer value changed

I made bindings to a C api (bullet physics engine) using cgo, some functions make use of data pointers. The idea is that I can attach a pointer to an object and retrieve it later when the physics engine invokes a callback. My problem is that when i get the value back, it change and I didn't do it. It seems that no source code is explicitelly changing the value.
CollisionObject: source, header,
The go codes that interracts with that class
heres how i send the values, the reconversion to *int and int is fine, the correct numbers are printed:
num := x*amounty*amountz + y*amountz + z + 1
ptr := unsafe.Pointer(&num)
fmt.Printf("created %v %v\n", ptr, *(*int)(ptr))
rb := sphere.RigidBody(ptr, 1)
But when I get it back from a raytest the value changed:
ptr := hit.GetUserPointer()
log.Printf("we got back: %v %v", ptr, *(*int)(ptr))
the pointer value itself didnt change, i can look up and see that there was a pointer pointing to this location, but the value its pointing at is different.
Now i'm wondering if maybe go didn't clean the value (garbage collected) since it wouldn't be used anymore and replaced this memory location with something else.
example output (with junk values removed):
created: 0xc2080006e0 40
2014/11/07 17:10:01 we got back: 0xc2080006e0 4921947622888946315
ANY pointer (hehe) is appreciated :)
Go's garbage collector doesn't know about the pointers held by C or C++ code, so there is nothing to keep the num variable alive.
You can work around this by storing a second copy of the pointer in a Go variable. One way is to use a global variable with a type like map[*C.some_c_type]*int or similar, and store &num there too. Remember to protect the map with a mutex so things behave correctly when you have concurrent access.
In order not to leak, you will need to manually delete &num from the map when the underlying C code is no longer holding a reference to it. If the C library provides the ability to set a destroy notify function when storing the user pointer, this will be easy: just export a Go function to C and use it as the notify function. If it doesn't, but the Go binding knows when the the pointer will be finished with (e.g. if the RigidBody variable is always freed via the Go API, you can do the clean up there.

When is it a good idea to return a pointer to a struct?

I'm learning Go, and I'm a little confused about when to use pointers. Specifically, when returning a struct from a function, when is it appropriate to return the struct instance itself, and when is it appropriate to return a pointer to the struct?
Example code:
type Car struct {
make string
model string
}
func Whatever() {
var car Car
car := Car{"honda", "civic"}
// ...
return car
}
What are the situations where I would want to return a pointer, and where I would not want to? Is there a good rule of thumb?
There are two things you want to keep in mind, performance and API.
How is a Car used? Is it an object which has state? Is it a large struct? Unfortunately, it is impossible to answer when I have no idea what a Car is. Truthfully, the best way is to see what others do and copy them. Eventually, you get a feeling for this sort of thing. I will now describe three examples from the standard library and explain why I think they used what they did.
hash/crc32: The crc32.NewIEEE() function returns a pointer type (actually, an interface, but the underlying type is a pointer). An instance of a hash function has state. As you write information to a hash, it sums up the data so when you call the Sum() method, it will give you the state of that one instance.
time: The time.Date function returns a Time struct. Why? A time is a time. It has no state. It is like an integer where you can compare them, preform maths on them, etc. The API designer decided that a modification to a time would not change the current one but make a new one. As a user of the library, if I want the time one month from now, I would want a new time object, not to change the current one I have. A time is also only 3 words in length. In other words, it is small and there would be no performance gain in using a pointer.
math/big: big.NewInt() is an interesting one. We can pretty much agree that when you modify a big.Int, you will often want a new one. A big.Int has no internal state, so why is it a pointer? The answer is simply performance. The programmers realized that big ints are … big. Constantly allocating each time you do a mathematical operation may not be practical. So, they decided to use pointers and allow the programmer to decide when to allocate new space.
Have I answered your question? Probably not. It is a design decision and you need to figure it out on a case by case basis. I use the standard library as a guide when I am designing my own libraries. It really all comes down to judgement and how you expect client code to use your types.
Very losely, exceptions are likely to show up in specific circumstances:
Return a value when it is really small (no more than few words).
Return a pointer when the copying overhead would substantially hurt performance (size is a lot of words).
Often, when you want to mimic an object-oriented style, where you have an "object" that stores state and "methods" that can alter the object, then you would have a "constructor" function that returns a pointer to a struct (think of it as the "object reference" as in other OO languages). Mutator methods would have to be methods of the pointer-to-the-struct type instead of the struct type itself, in order to change the fields of the "object", so it's convenient to have a pointer to the struct instead of a struct value itself, so that all "methods" will be in its method set.
For example, to mimic something like this in Java:
class Car {
String make;
String model;
public Car(String myMake) { make = myMake; }
public setMake(String newMake) { make = newMake; }
}
You would often see something like this in Go:
type Car struct {
make string
model string
}
func NewCar(myMake string) *Car {
return &Car{myMake, ""}
}
func (self *Car) setMake(newMake string) {
self.make = newMake
}

Resources