2014-11-04 206 views
2

我是新來的,並試圖使一個簡單的網絡爬蟲。我不斷收到「恐慌:運行時錯誤:無效的內存地址或零指針解引用」,並不知道如何解決這個問題。我有一個「advancedFetcher」函數和一個「basicFetcher」函數,我在任何一個下面都會得到相同的錯誤。 This answer建議檢查每個錯誤(我認爲這是我的錯誤),但我仍然收到錯誤。謝謝!運行時錯誤:無效的內存地址或零指針解除引用

package main 

import (
    "crypto/tls" 
    "fmt" 
    "io/ioutil" 
    "net" 
    "net/http" 
    "time" 
) 

var tr = &http.Transport{ 
    TLSClientConfig:  &tls.Config{InsecureSkipVerify: true}, 
    MaxIdleConnsPerHost: 25, 
    DisableKeepAlives: true, 
    Proxy:    http.ProxyFromEnvironment, 
    Dial: (&net.Dialer{ 
     Timeout: 10 * time.Second, 
     KeepAlive: 10 * time.Second, 
    }).Dial, 
    TLSHandshakeTimeout: 5 * time.Second, 
} 
var client = &http.Client{Transport: tr} 

func makeGetRequest(uri string) *http.Response { 
    req, err := http.NewRequest("GET", uri, nil) 
    if err != nil { 
     fmt.Println(err) 
    } 
    req.Header.Add("User-Agent", "Hi it's me again") 
    resp, err := client.Do(req) 
    if err != nil { 
     fmt.Println(err) 
    } 
    return resp 
} 

func advancedFetcher(uri string, c chan int) { 
    fmt.Println("Getting: ", uri) 
    resp := makeGetRequest(uri) 
    defer resp.Body.Close() 
    c <- resp.StatusCode 
} 

func basicFetcher(uri string, c chan int) { 
    fmt.Println("Getting: ", uri) 
    resp, err := http.Get(uri) 
    if err != nil { 
     fmt.Println(err) 
    } 
    defer resp.Body.Close() 
    _, err = ioutil.ReadAll(resp.Body) 
    c <- resp.StatusCode 
} 

func main() { 
    c := make(chan int) 
    rows := []string{"https://www.google.com", "http://www.fdicconnect.gov"} 
    for _, row := range rows { 
     //go basicFetcher(row, c) 
     go advancedFetcher(row, c) 
    } 
    for _ = range rows { 
     select { 
     case result := <-c: 
      fmt.Println(result) 
     } 
    } 
    fmt.Println("All Done") 
} 

編輯#1:

Getting: https://www.google.com 
Getting: http://www.fdicconnect.gov 
200 
Get http://www.fdicconnect.gov: dial tcp 167.176.6.86:80: i/o timeout 
panic: runtime error: invalid memory address or nil pointer dereference 
[signal 0xb code=0x1 addr=0x0 pc=0x400ff2] 

goroutine 21 [running]: 
runtime.panic(0x6594c0, 0x7e9b53) 
    /usr/local/go/src/pkg/runtime/panic.c:279 +0xf5 
main.advancedFetcher(0x6c3b70, 0x1a, 0xc208004180) 
    /home/me/go/src/testfolder/tester/main.go:41 +0x1c2 
created by main.main 
    /home/me/go/src/testfolder/tester/main.go:61 +0x123 

goroutine 16 [chan receive]: 
main.main() 
    /home/me/go/src/testfolder/tester/main.go:65 +0x198 

goroutine 19 [finalizer wait]: 
runtime.park(0x413bd0, 0x7ee660, 0x7ec8c9) 
    /usr/local/go/src/pkg/runtime/proc.c:1369 +0x89 
runtime.parkunlock(0x7ee660, 0x7ec8c9) 
    /usr/local/go/src/pkg/runtime/proc.c:1385 +0x3b 
runfinq() 
    /usr/local/go/src/pkg/runtime/mgc0.c:2644 +0xcf 
runtime.goexit() 
    /usr/local/go/src/pkg/runtime/proc.c:1445 

goroutine 17 [syscall]: 
runtime.goexit() 
    /usr/local/go/src/pkg/runtime/proc.c:1445 
+1

您的程序在恐慌之前是否打印了錯誤?如果內存服務,如果'http.Get'返回一個錯誤,'resp.Body'是'nil'這會導致你的錯誤。 – 2014-11-04 01:18:35

+0

@JimmySawczuk:你的意思是像編輯#1?如果是這樣,我仍然會得到同樣的錯誤。 – 2014-11-04 01:24:37

+2

什麼是投擲恐慌? – 2014-11-04 01:25:38

回答

3

是您的程序恐慌之前打印錯誤?如果內存服務,如果http.Get返回一個錯誤,然後resp.Body == nil,這將導致您的錯誤,因爲您不能撥打resp.Body.Close()nil

由於twotwotwo suggests,你應該編寫你的函數,以便它返回一個(結果,錯誤)對,以便在遇到問題之前可以正常終止它。

+0

和thx幫助newb! – 2014-11-04 17:49:54

相關問題