ホームページ > バックエンド開発 > Golang > 範囲ループを使用して Go スライスからコピーするとメモリ アドレスが重複する場合があるのはなぜですか?

範囲ループを使用して Go スライスからコピーするとメモリ アドレスが重複する場合があるのはなぜですか?

Linda Hamilton
リリース: 2024-12-23 19:17:15
オリジナル
947 人が閲覧しました

Why Does Copying from a Go Slice with a Range Loop Sometimes Duplicate Memory Addresses?

Go でスライスからコピーするときにメモリ アドレスを再利用する

Go で範囲を使用してスライスから値をコピーするという奇妙な動作が発生しました。ループの結果、出力内のメモリ アドレスが重複しました。これを解決するには、コードを変更して一時変数を作成し、予期した個別のアドレスを生成しました。

この現象が発生するのは、元のコードでは、ループ変数 item がスライスの現在の要素へのポインタであるためです。 。スライスを反復処理すると、Go はこのポインター変数を再利用し、反復ごとに値を変更しますが、同じメモリ アドレスを維持します。その結果、&item を出力スライスに割り当てると、同じメモリ アドレスを誤って複数回複製することになります。

この再利用を防ぐために、変更されたコードは、現在の要素のコピーを保持する一時変数 i を作成します。これにより、Go は反復ごとに新しいメモリ割り当てを作成することになり、出力スライス内に一意のアドレスが生成されます。

この概念を説明するために、次の例を考えてみましょう。

package main

import "fmt"

type Region struct {
    Name string
}

func main() {
    // Create a slice of Region objects.
    regions := []Region{
        {Name: "Central"},
        {Name: "East"},
    }

    // Original code - duplicates memory addresses
    fmt.Println("Original Code:")
    models1 := make([]Model, len(regions))
    for idx, item := range regions {
        models1[idx] = &item
    }
    for _, m := range models1 {
        fmt.Println(m)
    }

    // Modified code - generates unique memory addresses
    fmt.Println("Modified Code:")
    models2 := make([]Model, len(regions))
    for idx, _ := range regions {
        i := regions[idx]
        models2[idx] = &i
    }
    for _, m := range models2 {
        fmt.Println(m)
    }
}
ログイン後にコピー

このコードの実行元のコードでは重複したメモリ アドレスが出力されるのに対し、変更されたコードでは一意のアドレスが生成されることがわかります。

以上が範囲ループを使用して Go スライスからコピーするとメモリ アドレスが重複する場合があるのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート