>  기사  >  백엔드 개발  >  Go 언어의 스택과 힙은 무엇인가요?

Go 언어의 스택과 힙은 무엇인가요?

青灯夜游
青灯夜游원래의
2023-01-03 10:35:044070검색

스택은 실행 스레드를 위해 예약된 메모리 공간인 데이터 구조입니다. 스택은 데이터를 선형 테이블의 한쪽 끝에만 넣은 다음 이 끝에서 데이터를 꺼냅니다. 스택의 요소는 먼저 들어간 것, 마지막으로 나온 것, 마지막으로 들어간 것, 처음 나온 것의 순서입니다. 힙은 동적 할당을 위해 예약된 메모리 공간인 데이터 구조입니다. 스택과 달리 힙에서 블록을 할당하고 재할당하기 위한 고정된 패턴은 없으며 언제든지 할당하고 해제할 수 있습니다.

Go 언어의 스택과 힙은 무엇인가요?

이 튜토리얼의 운영 환경: Windows 7 시스템, GO 버전 1.18, Dell G3 컴퓨터.

Go 언어의 스택과 힙

프로그래밍 언어에는 힙과 스택이라는 두 가지 중요한 개념이 있습니다.

힙과 스택은 프로그램을 편집할 때 자주 사용되는 두 가지 매우 중요한 데이터 구조입니다.

이 두 가지 데이터 구조를 살펴보겠습니다.

Stack

스택은 선형 리스트의 한쪽 끝에만 데이터를 넣을 수 있도록 허용하고, 이 끝에서 데이터를 꺼냅니다. 즉, 스택에 있는 요소를 순서대로 꺼냅니다. 먼저 들어간 것, 마지막으로 나온 것, 마지막으로 들어간 것, 먼저 나온 것.

요소를 스택에 넣는 과정을 푸시라고 합니다. 스택에 푸시하면 스택에 있는 요소 수가 증가합니다. 스택에 넣은 마지막 요소는 스택의 맨 위에 있고, 스택에 넣은 첫 번째 요소는 스택의 맨 아래에 있습니다.

스택에서 요소를 꺼낼 때는 스택의 맨 위에서만 꺼낼 수 있습니다. 요소를 꺼낸 후에는 스택 수가 더 작아지고 항상 마지막에 놓인 요소가 제거됩니다. 마지막에 넣은 것은 항상 먼저 꺼내집니다.

Go 언어의 스택과 힙은 무엇인가요?

우리는 종종 스택 사용을 시뮬레이션하기 위해 배열을 사용합니다.

스택을 푸시하고 팝하는 구현 코드는 다음과 같습니다.

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()                    //显示
}

Heap

메모리 할당의 힙은 다음과 유사합니다. 방에 배치하기 다양한 가구를 배치하려면 가구의 크기가 클 수도 있고 작을 수도 있습니다. 메모리 할당 시 가구를 배치하기 전에 가구를 놓을 수 있을 만큼 큰 공간을 찾아야 합니다.

가구를 배치하고 비우기를 반복하다 보면 방 안의 공간이 지저분해질 것입니다. 이때 이 공간에 가구를 배치하면 공간은 충분하지만 각 공간이 서로 다른 공간으로 분산되어 있다는 것을 알게 될 것입니다. 가구를 배치할 연속적인 공간이 없습니다. 이때 메모리 할당자는 이러한 공간을 조정하고 최적화해야 합니다.

Go 언어의 스택과 힙은 무엇인가요?

힙 할당 메모리와 스택 할당 메모리에 비해 힙은 예측할 수 없는 크기의 메모리 할당에 적합합니다.

힙 및 스택 할당

변수 정의가 완료된 후 일반적으로 힙 및 스택 공간에 할당됩니다. 어떤 공간이 존재하는지는 메모리의 동적 할당(new/malloc)이 있는지에 따라 다릅니다.

예를 들어 다음과 같은 경우

Case 1

var p *int    //全局指针变量
func f(){
    var i int
    i = 1
    p = &i    //全局指针变量指向局部变量i
}

Case 2

func f(){
    p := new(int) //局部指针变量,使用new申请的空间
    *p = 1
}

첫 번째 경우에는 var를 사용하여 지역 변수를 정의하는데, 전역 포인터 변수 p에 i를 대입하므로 함수가 끝나면, i는 해제되지 않으므로 지역 변수 i가 힙에 할당됩니다(프로그래머가 수동으로 해제함).

  • 로컬 변수: 함수에 정의된 변수이며 동적 수명 주기를 가집니다. 실행될 때마다 새로운 엔터티가 생성되고 아무도 이를 사용하지 않을 때까지 유지됩니다(예: 외부 포인터가 이를 가리키지 않을 때, 함수가 종료됩니다. 이 변수에 접근할 수 있는 경로가 없습니다.) 이 때, 차지하는 공간은 회수됩니다

두 번째 경우에는 p를 적용하기 위해 new를 사용합니다. 함수 종료 후 릴리즈되며 p는 스택에 적용됩니다(자동 릴리즈)

【관련 권장 사항: Go 비디오 튜토리얼, 프로그래밍 교육

위 내용은 Go 언어의 스택과 힙은 무엇인가요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.