2017-10-09 133 views
-4

我搜索了很多找到解決這個錯誤,但沒有任何工作。當我在main函數中使用查詢時,它工作正常,但是當我將它傳遞給Group函數時,它會發生混亂。這裏是代碼:無效的內存地址或零指針解引用golang數據庫

package main 

import (
    "database/sql" 
    "encoding/json" 
    "fmt" 
    "net/http" 
    "strconv" 
    "strings" 
) 

var db *sql.DB 
var err error 

type Row struct { 
    Id   int 
    Title  string `json:"title,omitempty"` 
    Adress  string `json:"adress,omitempty"` 
    Tozihat string `json:"tozihat,omitempty"` 
    Mobile  string `json:"mobile,omitempty"` 
    Phone  string `json:"phone,omitempty"` 
    Mapid  string `json:"mapid,omitempty"` 
    Location string `json:"location,omitempty"` 
    Keywords string `json:"keyword,omitempty"` 
    Imagepath1 string `json:"imagepath1,omitempty"` 
    Imagepath2 string `json:"imagepath2,omitempty"` 
    Category string `json:"category,omitempty"` 
    Catid  int `json:"catid,omitempty"` 
} 

func Group(res http.ResponseWriter, req *http.Request) { 
    u := req.URL.RequestURI() 
    Id := strings.Split(u, "/")[2] 
    catId, errconv := strconv.Atoi(Id) 
    if errconv != nil { 
      fmt.Println(errconv) 
    } 
    rows, errrows := db.Query("select title, location, category from Total where catID=(?)", catId) 
    if errrows != nil { 
      fmt.Println(errrows) 

    } 

    defer rows.Close() 
    var results []Row 
    var result Row 

    for rows.Next() { 

      errr := rows.Scan(&result.Title, &result.Location, &result.Category) 
      if errr != nil { 
        fmt.Println(errr) 

      } 

      results = append(results, result) 
    } 
    fmt.Println(results) 
    jsonresults, errj := json.Marshal(results) 
    if errj != nil { 
      fmt.Print("error marshaling results", errj) 
    } 
    res.Header().Set("Content-Type", "application/json") 

    res.Write(jsonresults) 

} 

func main() { 
    http.HandleFunc("/group/", Group) 

    http.ListenAndServe(":9001", nil) 

    db, err = sql.Open("mysql", "root:[email protected]/bartarinha") 
    if err != nil { 
      fmt.Println(err) 
    } 
    defer db.Close() 
    errPing := db.Ping() 
    if errPing != nil { 
      fmt.Println(errPing) 
    } 
} 

任何幫助表示讚賞。錯誤看起來是這樣的: 2017/10/09 22:43:44 http:panic serving [:: 1]:41618:運行時錯誤: 無效的內存地址或零指針解除引用 goroutine 7 [running]: net/HTTP(*康涅狄格州).serve.func1(0xc420088820) /usr/local/go/src/net/http/server.go:1721 + 0xd0

panic(0x688060, 0x81fc40) 
    /usr/local/go/src/runtime/panic.go:489 +0x2cf 
database/sql.(*DB).conn(0x0, 0x7fe580, 0xc4200102b0, 0x1, 0x6dac6a, 
0xd10000000000000e, 0xe) 
    /usr/local/go/src/database/sql/sql.go:896 +0x3a 
database/sql.(*DB).query(0x0, 0x7fe580, 0xc4200102b0, 0x6e7aff, 0x3b,     
0xc420047aa8, 0x1, 0x1, 0x1, 0xc42002cc00, ...) 
    /usr/local/go/src/database/sql/sql.go:1245 +0x5b 
database/sql.(*DB).QueryContext(0x0, 0x7fe580, 0xc4200102b0, 0x6e7aff, 
0x3b, 0xc420047aa8, 0x1, 0x1, 0xc4200e01a0, 0xc42003ca40, ...) 
    /usr/local/go/src/database/sql/sql.go:1227 +0xb8 
database/sql.(*DB).Query(0x0, 0x6e7aff, 0x3b, 0xc42003caa8, 0x1, 0x1, 
0x8, 0xc4200d8038, 0xc420016e40) 
    /usr/local/go/src/database/sql/sql.go:1241 +0x82 
main.Group(0x7fe080, 0xc4200f82a0, 0xc42000a900) 
    /home/behrooz/gp_projects/src/samples/kabootar/main.go:40 +0x230 
net/http.HandlerFunc.ServeHTTP(0x6e9d38, 0x7fe080, 0xc4200f82a0, 
0xc42000a900) 
    /usr/local/go/src/net/http/server.go:1942 +0x44 
net/http.(*ServeMux).ServeHTTP(0x8293c0, 0x7fe080, 0xc4200f82a0, 
0xc42000a900) 
    /usr/local/go/src/net/http/server.go:2238 +0x130 
net/http.serverHandler.ServeHTTP(0xc4200942c0, 0x7fe080, 0xc4200f82a0, 
0xc42000a900) 
    /usr/local/go/src/net/http/server.go:2568 +0x92 
net/http.(*conn).serve(0xc420088820, 0x7fe540, 0xc420014940) 
    /usr/local/go/src/net/http/server.go:1825 +0x612 
created by net/http.(*Server).Serve 
    /usr/local/go/src/net/http/server.go:2668 +0x2ce 
+4

你沒有處理錯誤,你只是將它們打印出來。 – JimB

+4

'http.ListenAndServe'塊。之後的代碼實際上都沒有運行。 – Peter

+1

另外,在某些情況下'http.ListenAndServe'可能返回一個錯誤。你應該檢查一下。但JimB是正確的,你打印錯誤,但沒有正確處理它們。我的猜測是,返回'nil,error',並且你打印錯誤,然後輕率地假設數據值(無)是好的。沒有看到更多的程序輸出,我們無法確定地說。 –

回答

1

因此崩潰是由DB指針引起的無。這意味着嘗試在第40行上使用該連接的代碼會導致恐慌。

rows, errrows := db.Query(... 

的DB指針爲零,因爲正如彼得指出,http.ListenAndServe阻止,這意味着沒有它將運行後。

嘗試在本地運行這個例子,看看問題:

package main 

import (
    "net/http" 
) 

func Group(res http.ResponseWriter, req *http.Request) { 
    println("group handler") 
} 

func main() { 
    http.HandleFunc("/group/", Group) 
    err := http.ListenAndServe(":9001", nil) 
    if err != nil { 
     panic(err) 
    } 
    println("Running code after ListenAndServe (only happens when server shuts down)") 
} 

你不會看到運行代碼的消息。

+0

謝謝大家,你的回答給了我深刻的見解。最後,我將http.ListenAndServe替換爲代碼的底部以轉義該塊。 –

相關問題