상세 컨텐츠

본문 제목

부스트코딩 뉴비챌린지 스터디 5주차 : 메모리 교환, 스택, 힙

IT/스터디

by J KIMS 2020. 9. 9. 15:50

본문

반응형

5주차는 내용이 많아서 여러개로 나눠 올리는 중입니다. 💦

 

7) 메모리 교환, 스택, 힙

 

늘 여러가지 소품을 들고 나와서 재밌게 수업을 진행하시는 🤣👍👍

a와 b를 교환하는 swap 함수를 만들려면 포인터에 대한 이해가 필요하다.

(함수로 만들지 않는다면 포인터 없이도 가능)

 

먼저 컴퓨터의 메모리 속 공간이 어떻게 되는지 살펴보고 가겠다.

 

 

컴퓨터의 메모리는 구조적으로 사용된다.

 

맨 위에는 0과 1로 컴파일된 머신코드가 들어간다. 그 아래 globals는 프로그램이 전역 변수가 저장된다. 

이것은 사람들이 컴파일러를 만들 때 정해둔 규칙이다.

 

globals 아래에는 힙(heap)이라는 특별한 공간이 있다. 힙은 우리가 메모리를 할당받을 수 있는 커다란 영역으로 malloc 함수도 여기서 메모리를 가져온다. 힙은 아래 방향으로 메모리를 쌓아간다.

 

제일 아래 스택(stack)에는 함수의 지역변수들이 저장된다. 메인 함수의 인자와 지역변수들이 스택 제일 아래쪽에 저장되고 프로그램에 다른 함수가 존재한다면 그 위에 쌓이게 된다. 이런 식으로 스택은 윗방향으로 점점 공간을 차지하게 된다.

 

#include <stdio.h>

void swap(int a, int b);

int main(void){
    int x, y;

    printf("a, b를 입력하세요 : ");
    scanf("%d %d", &x,&y);

    printf("%d %d\n", x, y);

    // x y 교환하기
    swap(x, y);
    printf("%d %d\n", x, y);

    return 0;
}

void swap(int a, int b){
    int temp;

    temp = a;
    a = b;
    b = temp;
}

 

위의 코드를 실행시켜보아라. x와 y의 값이 바뀌어서 출력되는가? 그렇지 않을 것이다.

이는 swap 함수에 x와 y의 값을 복사해서 전달한 것에 불과하기 때문이다.

 

위의 프로그램이 메모리에서 차지하는 공간은 대강 이런 이미지이다.

 

 

스택의 제일 아래에 메인함수의 지역변수들이 존재하고 메인함수가 swap함수를 호출하면 윗 공간을 swap함수에할당한다.

 

스택의 제일 아래 영역에는 변수 x,y가 그 위에는 a,b,temp 가 존재한다.

 

swap함수가 실행되는 동안 a와 b 사이의 값 교환이 이루어질 것이다. 하지만 함수의 실행이 끝나면? 오른쪽과 같이 스택에서 사라져버린다! main 함수의 x와 y의 값은 교환되지 않은 채 그대로이다.

 

하지만 포인터를 사용하면 변수 a와 b가 직접 x와 y를 가리키게 하여 값을 수정하는 게 가능하다.

 

#include <stdio.h>

void swap(int* a, int* b);

int main(void){
    int x, y;

    printf("a, b를 입력하세요 : ");
    scanf("%d %d", &x,&y);

    printf("%d %d\n", x, y);

    // x y 교환하기
    swap(&x, &y); // x와 y의 주소값 전달
    printf("%d %d\n", x, y);

    return 0;
}

void swap(int* a, int* b){
    int temp;

    temp = *a;
    *a = *b;
    *b = temp;
}

 

이 프로그램에서 달라진 것은 swap 함수 안에서 a와 b는 포인터 변수가 되었고, 메인 함수 안에서 swap함수에게 x와 y의 주소를 전달했다는 것이다.

 

 

포인터 변수 a, b에는 x와 y의 주소가 저장되어 있으므로 위와 같이 x와 y를 가리킨다.

참조연산자*로 x와 y의 값에 접근하여 직접 값을 바꾸는 게 가능해진다. 

 

이로써 x와 y 값의 교환에 성공했고 실행이 끝난 swap함수는 스택에서 사라진다.

임시로 변수를 저장하는 temp 변수도 더 이상 필요없으니 사라져도 무관하다.

 

 

💡 스택 오버플로우 (stack overflow) vs 힙 오버플로우 (heap overflow)

 

스택은 메모리의 아래에서 위로 공간을 늘려가고 힙은 위에서 아래로 공간을 늘려간다.

 

만약 재귀 함수처럼 자기 자신을 계속 호출하는 프로그램을 사용한다면 스택은 점점 위로 쌓여서 힙과 충돌할 것이다. 이것이 스택 오버플로우이다. 프로그래머들에게 유명한 사이트인데 바로 여기에서 유래했다.

 

반대로 malloc으로 계속해서 힙에서 메모리를 할당받으면 아래로 차곡차곡 쌓여 언젠가는 스택과 충돌할 것이다. 이건 힙 오버플로우이다.

 

이는 한정된 메모리에서 어쩔 수 없이 발생하는 일이다. 따라서 메모리에 너무 많은 것들을 저장하다보면 에러를 일으킬 수 있다. 컴퓨터에 너무 많은 것들을 저장해서 파일이나 사진이 열리지 않는 경험을 해 본 적 있을 것이다. 이런 현상들을 버퍼 오버플로우라고 한다.

 

반응형

관련글 더보기

댓글 영역