메모리 누수
- malloc 함수를 이용하여 메모리를 할당한 후에는 free라는 함수를 이용하여 메모리를 해제해줘야 한다.
- 그렇지 않은 경우 메모리에 저장한 값은 쓰레기 값으로 남게 되어 메모리 용량의 낭비가 발생하게 되기 때문
- 이러한 현상을 ‘메모리 누수’라고 한다.
※ valgrind라는 프로그램을 사용하면 우리가 작성한 코드에서 메모리와 관련된 문제가 있는지를 쉽게 확인할 수 있다.
다음과 같은 명령어를 사용하면 filename 파일에 대한 valgrind의 검사 내용을 쉽게 확인할 수 있다.
- f 함수를 살펴보면 먼저 포인터 x에는 int형의 사이즈(4바이트)에 10배에 해당하는 크기의 메모리, 즉 40바이트를 할당한다.
- 그리고 x의 10번째 값으로 0을 할당한다.
- 그리고 main 함수에서 f를 실행하게 되는데,
- 이 코드를 valgrind 로 검사해보면 버퍼 오버플로우와 메모리 누수 두 가지 에러를 확인할 수 있다.
- 먼저 버퍼 오버플로우는 x[10] = 0; 코드로 인해 발생한다.
- 우리는 10개의 int형의 배열을 만들었는데 배열의 인덱스가 0부터 시작한다는 점을 감안하면 인덱스 10은 11번째 인덱스에 접근하겠다는 의미이고, 이는 정의되지 않은 것이기 때문에 버퍼 오버플로우가 발생하는 것
- 따라서 이 오류는 0에서 9 사이의 인덱스를 사용하면 해결할 수 있다.
- 또한 메모리 누수는 x라는 포인터를 통해 할당한 메모리를 해제하기 위해 free(x) 라는 코드를 추가해줌으로써 해결할 수 있다.
메모리 교환, 스택, 힙
① 예제 1 swap 함수
- 함수 swap은 정수 a와 b를 입력받아 그 값을 바꾸는 일을 수행한다.
- main 함수에서는 x에 1, y에 2를 입력하고 swap 함수를 통해 그 두 값을 바꾸려고 하고 있다.
- 그러나 위 코드를 컴파일하고 출력해보면 의도와는 다르게 swap 함수를 거친 후에도 x와 y의 값이 바뀌지 않은채 그대로 출력된다.
- 사실 swap 함수는 교환 작업을 제대로 수행하고 있는데, 문제는 교환하는 대상이 x, y 그 자체가 아닌 함수 내에서 새롭게 정의된 a, b라는 것
- a와 b는 각각 x와 y의 값을 복제하여 가지게 된다. 서로 다른 메모리 주소에 저장되는 것.
② 데이터 저장 구역
- 그림에서와 같이 메모리 안에는 데이터 저장되는 구역이 나뉘어져 있다.
- 머신 코드 영역에는 우리 프로그램이 실행될 때 그 프로그램이 컴파일된 바이너리가 저장
- 글로벌 영역에는 프로그램 안에서 저장된 전역 변수가 저장
- 힙 영역에는 malloc으로 할당된 메모리의 데이터가 저장
- 스택에는 프로그램 내의 함수와 관련된 것들이 저장
- 이를 바탕으로 다시 생각해보면, 위의 코드에서 a, b, x, y, tmp 모두 스택 영역에 저장되지만
- a와 x, b와 y는 그 안에서도 서로 다른 위치에 저장된 변수!
- 따라서 a와 b를 바꾸는 것은 x와 y를 바꾸는 것에 아무런 영향도 미치지 않는 것
- 따라서 아래 그림 및 코드와 같이 a와 b를 각각 x와 y를 가리키는 포인터로 지정함으로써 이 문제를 쉽게 해결할 수 있다.
'boostcourse > CS50' 카테고리의 다른 글
CS50 6. 자료구조(1) - 배열의 크기 조정하기, 연결 리스트 (0) | 2022.10.25 |
---|---|
CS50 5. 메모리(4) - 파일 쓰기, 파일 읽기 (0) | 2022.10.25 |
CS50 5. 메모리(2) - 문자열, 문자열 비교, 문자열 복사 (0) | 2022.10.24 |
CS50 5. 메모리(1) - 메모리 주소, 포인터 (0) | 2022.10.24 |
CS50 4. 알고리즘(3) - 정렬 알고리즘의 실행시간, 재귀, 병합 정렬 (0) | 2022.10.24 |