スタックはデータ構造であり、実行スレッド用に予約されたメモリ空間です。スタックでは線形テーブルの一端にのみデータを入れることができ、データはこの端から取り出されます。つまり、先入れ後出し、後入れ先出しに従って、削除される順序でスタックから要素を削除します。ヒープは、動的割り当て用に予約されたメモリ領域であるデータ構造です。スタックとは異なり、ヒープからのブロックの割り当てと再割り当てに固定パターンはなく、いつでも割り当てと解放ができます。
このチュートリアルの動作環境: Windows 7 システム、GO バージョン 1.18、Dell G3 コンピューター。
プログラミング言語には、ヒープとスタックという 2 つの非常に重要な概念があります。
ヒープとスタックは 2 つの非常に重要なデータです。構造はよく使用されます。プログラムを編集するとき、Go 言語も例外ではありません。
これら 2 つのデータ構造を見てみましょう。
スタック
スタックでは、線形テーブルの一方の端にのみデータを入れることができ、データはこの端で取り出されます。 end、つまり、先入れ後出しに従って、後入れ先出しの順序でスタックから要素を削除します。
要素をスタックに入れるプロセスはプッシュと呼ばれます。スタックにプッシュすると、スタック上の要素の数が増加します。スタックに最後に置かれた要素はスタックの一番上にあり、スタックに最初に置かれた要素はスタックの一番下にあります。
スタックから要素を取り出す場合、スタックの先頭からのみ取り出すことができます。要素を取り出すとスタックの番号は小さくなり、最初に入れられた要素が常に取り出されます。最後に入れられた要素が常に取り出されます。最初に取り出されます。
スタックの使用をシミュレートするために配列をよく使用します:
スタックのプッシュとポップの実装コードは次のとおりです:
package main import ( "fmt" "errors" ) //使用数组来模拟一个栈的使用 type Stack struct { MaxTop int // 表示我们栈最大可以存放数个数 Top int // 表示栈顶, 因为栈顶固定,因此我们直接使用Top arr [5]int // 用一个数组模拟栈 } //入栈函数 func (this *Stack) Push(val int) (err error) { //先判断栈是否满了 if this.Top == this.MaxTop - 1 { fmt.Println("stack full") return errors.New("stack full") } this.Top++ //放入数据 this.arr[this.Top] = val return } //出栈函数 func (this *Stack) Pop() (val int, err error) { //判断栈是否空 if this.Top == -1 { fmt.Println("stack empty!") return 0, errors.New("stack empty") } //先取值,再 this.Top-- val = this.arr[this.Top] this.Top-- return val, nil } //遍历栈,注意需要从栈顶开始遍历 func (this *Stack) List() { //先判断栈是否为空 if this.Top == -1 { fmt.Println("stack empty") return } fmt.Println("栈的情况如下:") for i := this.Top; i >= 0; i-- { fmt.Printf("arr[%d]=%d\n", i, this.arr[i]) } } func main() { stack := &Stack{ MaxTop : 5, // 表示最多存放5个数到栈中 Top : -1, // 当栈顶为-1,表示栈为空 } //入栈 stack.Push(1) stack.Push(2) stack.Push(3) stack.Push(4) stack.Push(5) stack.List()//显示 //出栈 val, _ := stack.Pop() fmt.Println("出栈val=", val) // 5 stack.List() //显示 }
ヒープ
メモリ割り当てにおけるヒープは、部屋にさまざまな家具を配置するのと似ており、家具のサイズは大きくても小さくてもかまいません。家具を見つける必要があるので、家具が収まる十分な広さのスペースに家具を置きます。
家具を置いたり置いたりを繰り返すと、部屋の中の空間が乱雑になってしまいますが、この空間に家具を置くと、十分なスペースがあるのに、それぞれの空間がバラバラになってしまいます。 、家具を置くための連続したスペースがありません。現時点では、メモリ アロケータはこれらのスペースを調整して最適化する必要があります。
ヒープ割り当てメモリやスタック割り当てメモリと比較して、ヒープは予測できないサイズのメモリ割り当てに適しています。
ヒープとスタックの割り当て
変数定義が完了すると、通常はヒープとスタック領域に割り当てられます。それはどの空間に存在しますか? それは、メモリの動的割り当て (new/malloc) があるかどうかによって異なります。
たとえば、次のケースです。
ケース 1
var p *int //全局指针变量 func f(){ var i int i = 1 p = &i //全局指针变量指向局部变量i }
ケース 2
func f(){ p := new(int) //局部指针变量,使用new申请的空间 *p = 1 }
最初のケースでは、var を使用してローカル変数を定義していますが、 i の割り当てによる グローバル ポインタ変数 p を指定すると、関数が終了しても i はこの時点では解放されないため、ローカル変数 i がヒープに適用されます (プログラマが手動で解放します)。
2 番目のケースでは、new を使用してスペースを適用します、関数を終了すると p が失われるため、関数が解放されるため、p はスタックに適用されます (自動的に解放されます)
[関連する推奨事項: Go ビデオ チュートリアル 、プログラミング教育]
以上がGo言語のスタックとヒープとは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。