This is a creation in Article, where the information may have evolved or changed.
Near the end of the day to write and debug a piece of Golang code, but the results are always inconsistent with expectations, weird, and still no fruit before work. The code demo is as follows:
Testpointer.go
Package Main
Import (
"FMT"
)
var p *int
Func foo () (*int, error) {
var i int = 5
Return &i, Nil
}
Func Bar () {
Use P
Fmt. Println (*P)
}
Func Main () {
P, Err: = foo ()
If err! = Nil {
Fmt. PRINTLN (ERR)
Return
}
Bar ()
Fmt. Println (*P)
}
This code is intended to define a global variable p in a package, initialize p with the return value of Foo (), and use P in bar. Expected Result: 5 is output in bar () and main (). But the result of the compilation execution is:
$go Run Testpointer.go
Panic:runtime Error:invalid memory address or nil pointer dereference
[Signal 0xb code=0x1 addr=0x0 PC=0X20D1]
Goroutine 1 [Running]:
Main.bar ()
/users/tony/test/go/testpointer.go:17 +0xd1
Main.main ()
/users/tony/test/go/testpointer.go:26 +0x11c
Goroutine 2 [runnable]:
Runtime.forcegchelper ()
/usr/local/go/src/runtime/proc.go:90
Runtime.goexit ()
/usr/local/go/src/runtime/asm_amd64.s:2232 +0x1
Goroutine 3 [runnable]:
Runtime.bgsweep ()
/usr/local/go/src/runtime/mgc0.go:82
Runtime.goexit ()
/usr/local/go/src/runtime/asm_amd64.s:2232 +0x1
Goroutine 4 [runnable]:
Runtime.runfinq ()
/usr/local/go/src/runtime/malloc.go:712
Runtime.goexit ()
/usr/local/go/src/runtime/asm_amd64.s:2232 +0x1
Exit Status 2
After supper, continue debugging this code. Why are you still crash? The code seems to have no problem, it is the go compiler problem, I use the latest 1.4, switch back to 1.3.3, the problem is still. It seems to be a problem with the code, but where is the problem? Add some print statements and look at:
Func bar () {
//use p
FMT. Printf ("%p,%t\n", p, p)//output:0x14dc80, 0x0, *int
fmt. Println (*P)//crash!!!
}
Func Main () {
Fmt. Printf ("%p,%t\n", p, p)//output:0x14dc80, 0x0, *int
P, Err: = foo ()
If err! = Nil {
Fmt. PRINTLN (ERR)
Return
}
Fmt. Printf ("%p,%t\n", p, p)//output:0x2081c6020, 0x20818a258, *int
Bar ()
Fmt. Println (*P)
}
By printing the output, it is found that P (0x2081c6020) and the global variable P (0X14DC80) returned from the Foo function are not an address, that is, not a variable. And from the debug output in bar (), the global variable p is not assigned to the address of the variable i in Foo when the Foo function returns, but remains a nil value, which causes the program to crash.
Well, nonsense, it's time to reveal the truth. The problem is ": =". In the scope of main, we use the
P, Err: = foo ()
The initial understanding is that Golang will define the new variable err,p the global variable that was originally defined. But the reality is that for variables that use: = defined, if the new variable p is not in a scope with the defined variable of the same name (this is the global variable p), then Golang will define the variable p to cover the global variable p, which is the real culprit that caused the problem.
Let's change the main function to:
Func Main () {
var err error
P, err = foo ()
If err! = Nil {
Fmt. PRINTLN (ERR)
Return
}
Bar ()
}
The execution result is exactly as expected.
Bigwhite. All rights reserved.