Aufruf von atomic.AddInt64 auf Feld eines Struct Panics invalid memory address or nil pointer dereference
, aber nicht, wenn wir Felder Reihenfolge neu ordnen; Warum?atomic.AddInt64 Verursacht ungültige Speicheradresse oder Nullzeiger-Dereferenz
Mit dieser Art:
type CountHandler struct {
c *RequestContext
count int64
}
Und ruft atomic.AddInt64(&countHandler.count, 1)
(Feld c
ist gleich Null an dieser Stelle) gerät in Panik. Aber nicht, wenn wir es umschreiben als:
type CountHandler struct {
count int64
c *RequestContext
}
Fehler verschwindet.
Ich denke, es sollte so sein, denn Go hält Daten im Speicher in einer sequentiellen Weise und erreicht einen nil
Wert bricht diese Sequenz (von Bytes); Doch ich frage mich, warum das so ist, denn ein Zeiger sollte eine feste Größe nil
oder einen anderen Wert haben.
Dies ist Go x86 1.4.2 auf Windows & vollständige Fehlermeldung lautet:
2015/02/23 12:56:44 http: panic serving [::1]:51886: runtime error: invalid memory address or nil pointer dereference
goroutine 5 [running]:
net/http.func·011()
c:/go/src/net/http/server.go:1130 +0xa8
sync/atomic.AddUint64(0x731144, 0x1, 0x0, 0x0, 0x263168)
c:/go/src/sync/atomic/asm_386.s:118 +0xc
main.(*CountHandler).ServeHTTP(0x731140, 0x263180, 0x122f6380, 0x122f62a0)
C:/Workshop/Devox/Workshop-Go/src/geoho/web/app/app.go:62 +0x42
github.com/julienschmidt/httprouter.func·001(0x263180, 0x122f6380, 0x122f62a0, 0x0, 0x0, 0x0)
C:/Workshop/Devox/Workshop-Go/src/github.com/julienschmidt/httprouter/router.go:232 +0x4c
github.com/julienschmidt/httprouter.(*Router).ServeHTTP(0x122d5d20, 0x263180, 0x122f6380, 0x122f62a0)
C:/Workshop/Devox/Workshop-Go/src/github.com/julienschmidt/httprouter/router.go:298 +0x141
net/http.serverHandler.ServeHTTP(0x122d2280, 0x263180, 0x122f6380, 0x122f62a0)
c:/go/src/net/http/server.go:1703 +0x145
net/http.(*conn).serve(0x122e01e0)
c:/go/src/net/http/server.go:1204 +0x9d8
created by net/http.(*Server).Serve
c:/go/src/net/http/server.go:1751 +0x2ce
ganze Quellcode ist (dieser Code ist falsch, ich war nur alice
über das Studium):
package main
import (
"fmt"
"github.com/julienschmidt/httprouter"
"github.com/justinas/alice"
"net/http"
"os"
"sync/atomic"
)
// play with alice
func main() {
c1 := alice.New(Counter, Texter).Then(nil)
router := httprouter.New()
router.Handler("GET", "/", c1)
router.GET("/kill", kill)
http.ListenAndServe(":27007", router)
}
func kill(rw http.ResponseWriter, rq *http.Request, pl httprouter.Params) {
os.Exit(0)
}
var ch CountHandler
// constructors:
func Counter(h http.Handler) http.Handler {
return &ch
}
func Texter(h http.Handler) http.Handler {
var t TextHandler
switch x := h.(type) {
case *CountHandler:
t.c = x.c
t.text = fmt.Sprintf("called so far %d", atomic.LoadInt64(&x.count))
}
return &t
}
// handlers:
type RequestContext struct {
val int
}
type CountHandler struct {
c *RequestContext
count int64
}
func (c *CountHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
atomic.AddInt64(&c.count, 1)
}
type TextHandler struct {
c *RequestContext
text string
}
func (t *TextHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
rw.Write([]byte(t.text))
}
Scheint wie ein Fehler für mich. Ich nahm Ihren Code und unter Linux läuft es gut. Gleiches auf dem Spielplatz. sehen Sie dies: http://play.golang.org/p/fDFaZPi3nf führt dieser genaue Code-Absturz auf Ihrem Windows-Rechner? –
Ja, es sollte funktionieren. Bitte poste mehr Code, z.B. wie Sie Ihre 'countHandler'-Variable erstellen. Bitte zielen Sie auf [MCVE] (http://stackoverflow.com/help/mcve). – icza
Danke; Ich habe den Code hinzugefügt. –