-
5. 메모리Computer Science/Boostcourse CS50 2021. 12. 24. 02:46728x90
메모리에 대하여 본격적으로 설명드리기 앞서, 익숙한 이야기부터 해보려 합니다.
어떠한 변수를 선언한 후 그 변수에 사용자가 원하는 값을 대입하기 위하여 항상 입력을 받았습니다.
#include <stdio.h> int main() { int var; scanf("%d",&var); }
위와 같이 입력을 받을 때는 변수 앞에 & 연산자가 왜 붙는지 궁금하실 겁니다.
&가 붙는 이유는 변수를 선언하면 컴퓨터 메모리 어딘가에 자료형의 크기만큼 메모리를 차지하는데, 여기서 차지하는 메모리마다 주소를 갖고 있습니다. 이 주소에 & 연산자를 통해 접근하여 메모리 공간 안에 있는 데이터를 변경시켜주기 위한 것입니다.
#include <stdio.h> int main() { int var; int *pvar = &var; scanf("%d",&var); printf("%d",*&var); printf("%d",*pvar); }
첫 번째 출력문과 같이 & 앞에 *(asterisk)를 붙인다면 해당 변수의 주소에 있는 메모리 공간에 접근을 하여 주솟값이 아닌 실제 데이터를 출력할 수 있습니다. 하지만 굳이 저렇게 작성하지 않아도 대부분은 쉽게 변수명 하나로만 출력을 합니다만 메모리 주소에 대해 자세히 알려드리기 위하여 설명을 드렸습니다.
pvar 변수를 보시면 변수 앞에 일반적인 변수와 달리 *가 붙은 걸 보실 수 있는데 이는 포인터 변수를 의미합니다.
포인터 변수란 특정 데이터가 저장된 변수의 주소를 저장하는 변수입니다. 처음에 쓰레기 값이 담긴 변수 var의 주소를 저장한 후, var에 입력을 받고 나면 당연히 포인터 변수가 가리키는 값도 쓰레기 값에서 바뀌게 됩니다.
포인터가 가리키고 있는 값을 출력해 주고 싶다면 두 번째 출력문에 나와있듯이 포인터 변수 앞에 *를 붙여 주면 되는 것이고, 만약 *를 붙이지 않는다면 위에서 저장한 변수의 주소가 출력됩니다.
실제 메모리 상으로는 위의 그림처럼 포인터 변수와 정수형 변수를 선언했을 때 어딘가 메모리 공간을 차지하게 되고, 50이라는 특정 데이터가 담긴 정수형 변수의 주솟값을 포인터 변수에 저장하게 되면 포인터 변수는 정수형 변수를 가리키게 되는 것입니다.
메모리의 구조는 네 구간으로 나누어지는데 머신 코드, 글로벌, 힙, 스택 영역으로 나누어집니다.
처음 머신 코드 영역의 경우에는 프로그램 실행 시 컴파일 된 소스코드의 바이너리가 저장이 되는 영역이고,
글로벌 영역은 전역 변수, 정적인 변수들이 저장되는 부분, 힙 영역은 동적으로 할당된 메모리의 데이터들이 저장되며 스택 영역은 함수와 관련된 데이터인 지역 변수 또는 매개 변수들이 저장되는 영역입니다.
힙 영역에서는 malloc 함수를 통해 정해진 크기만큼 메모리를 동적으로 할당할 수 있습니다.
주의할 점은 메모리 사용 후 메모리 용량의 낭비를 방지하기 위하여 반드시 free 함수로 메모리를 해제해 줘야 한다는 것입니다. 사용하지 않는 메모리가 있다면 메모리 누수 현상이 발생할 수도 있어 메모리가 비효율적으로 사용될 것입니다.
또한, 제한된 스택 영역에서 매우 많은 변수들이 저장되어 힙 영역을 침범하거나 힙 영역에서 해제하지도 않은 채 메모리를 계속 할당하게 된다면 스택 영역을 침범하는 overflow 현상이 발생하여 예상치 않은 문제가 생길 수 있습니다.
728x90'Computer Science > Boostcourse CS50' 카테고리의 다른 글
4-1 애너그램 판별 프로그램 (0) 2021.12.24 4. 알고리즘 (0) 2021.12.24 3-2 배열 Queue 구현 (0) 2021.12.24 3-1 학점 계산 프로그램 (0) 2021.12.24 3. 배열 (0) 2021.12.24