0

UPD : 結局のところ、Go でのエラー処理に関する質問です。

「メイン スレッド」で Web ページのアドレスを生成し、1 つの go-routine で実際のページを取得し、コンテンツを 経由で返しchan、別の go- でファイルに書き込む単純な Web クローラーを作成しました。ルーティーン。ただし、このプロセスを約 300,000 回繰り返した後、次のエラーが発生します。

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x38 pc=0x22e9]</pre>

エラー「stacktrace」は非常に長く、残念ながら今はありません(実験を繰り返した後、後で投稿します)。

どういうわけかメモリを管理したり、チャネルを閉じたりする必要はありますか?

以下、一部省略したコードです。

package main

import (
    "fmt"
    "io/ioutil"
    "net/http"
    "strconv"
)

func main() {
    channel := make(chan []byte)

    for i:=0; i < 20; i++ {
        go fetcher(generateLink(), channel)
    }

    for a:=0; ; a++ {
        go writeToFile(strconv.Itoa(a), <-channel)
        go fetcher(generateLink(), channel)
        fmt.Println(strconv.Itoa(a))
    }
}

func fetcher(url string, channel chan []byte) {

    resp, err := http.Get(url)
    if err != nil {
        channel <- []byte("")
    }
    defer resp.Body.Close()
    body, err := ioutil.ReadAll(resp.Body)
    channel <- body
}

func writeToFile(filename string, bytes []byte) {
    ioutil.WriteFile(filename+".html", bytes, 0644)
}

func generateLink() string {
    ...
}
4

3 に答える 3

3
panic: runtime error: invalid memory address or nil pointer deference

これは、nilポインターを使用しようとしたことを意味します。これはプログラマーエラーであり、メモリ不足エラーではありません。実際のトレースやコードにアクセスできないため、これ以上サポートすることはできません。


編集:あなたのコードをもう一度調べた後、私はエラーの考えられる原因を見つけたと思います。

resp, err := http.Get(url)
if err != nil {
    channel <- []byte("")
}
defer resp.Body.Close()

の場合でもresp、フィールドを取得するために参照することになります。の場合、respがnilである可能性が非常に高くなります。Bodyerr != nilerr !=nil

于 2012-08-17T20:29:26.320 に答える
1

スタックトレースがないため、ここでは推測にすぎません。しかし、次の 2 行は疑わしいように見えます。

body, err := ioutil.ReadAll(resp.Body)
channel <- body

チャネルで送信するときに、ボディが nil ではないことをどうやって知ることができますか? writeToFile もそれをチェックしないので、ファイルに nil バイトスライスを書き込もうとしている可能性が完全にあり、そこで爆発しています。エラーをキャプチャした場合は、続行する前に確認する必要があります。

于 2012-08-17T20:41:29.537 に答える
1

ある時点で への呼び出しがhttp.Get()失敗し、非 nil が返されますerrresp.Bodyこれが発生すると、空のバイト スライスをチャネルに入れますが、続行し、いずれにせよ読み込もうとしますresp

于 2012-08-17T20:54:37.863 に答える