Taking baby-developer steps
2022.02.02. gnl 메모리 해제, KO 케이스들 본문
오늘 목표
- gnlTest 테스터 Mandatory Part통과
- KO 뜨는 케이스 잡기
- 포인터 할당 해제 관련 문제 해결
오늘 한 일
- 어제 계획 세워둔 util 함수들 살펴보기를 진행했으나, substr, strjoin, strlcat, strlcpy 함수 내에서 free 함수를 사용한 적이 없기 때문에 포인터 할당 해제 관련해서 살펴볼 일은 없었다. (+메모리 누수는 없는 상태)
- 오늘 내로 KO 및 포인터 할당 해제 문제를 해결 못하면 처음 부터 다시 짜보는 것도 고려하고 있다. -> 처음부터 다시 짜는게 빠를것 같긴한데, 지금 내가 이 코드를 디버깅하면서 배울게 많은거 같애서 일단 디버깅을 계속하기로 결정했다.
- 포인터 할당 해제 관련 문제 해결
아직 포인터가 이중 할당 되는 문제를 잡는 중이지만, 왼쪽의 curr_buffer = buffers[fd]처럼 두개의 포인터(둘다 char *)가 같은 주소를 가리키게 하는게 얼마나 위험한지를 몸소 체험했다. 자꾸 이중 할당 되는 것 때문에 아래와 같이 free_memory 함수를 만들었었다.
위와 같이, 할당 해제한 포인터에는 널 포인터를 저장해둬서, 다시 한번 free_memory에 이미 할당 해제된 포인터가 들어오게 되면 아무일도 일어나지 않게 했다. 그러나, 두개의 포인터가 같은 주소를 가리키게 하는 경우에는 이 함수로는 중복 할당 문제를 해결 할 수 없다. 즉 curr_buffer = buffers[fd] 로 초기화 하면, 두 포인터가 같은 주소(가상의 주소 "0xA"를 가리킨다고 하자)를 가리킨다. 이 상태에서free_memory(&curr_buffer)를 하면, curr_buffer가 가리키는 주소(0xA)에 할당된 메모리는 해제되고, curr_buffer 포인터는 널을 가리키게 된다. 그러나 buffers[fd]는 여전히 0xA를 가리키고 있기 때문에 할당 해제된 공간을 가리키고 있는 일명 "댕글링 포인터"가 되게 된다. 이 상태에서 free_memory(&buffers[fd])를 하면, 할당 해제를 할 메모리가 없으므로 pointer being freed was not allocated 라는 error 메시지를 보게 되는 것이다.
댕글링 포인터의 정의는 알고 있었어서, 조심하기 위해 free()함수 호출 시 강박적으로 free함수에 들어간 포인터가 널값을 가리키게 하고 심지어는 함수로까지 빼뒀었는데, get_next_line함수를 25줄 이내로 만드려고 리팩토링 하다가 댕글링 포인터가 발생 할 수 있는 점을 놓쳤다. 일단 해당 문제는 curr_buffer = buffers[fd]로 curr_buffer에 buffers[fd]의 주소 값을 저장한 후에 buffers[fd]를 널값을 가리키게 함으로써 해결 했다. 그러나 아직 몇개의 케이스들에서 여전히 이중 할당 문제가 발생하고 있어서 더 살펴보고 있는 중이다.
메모
char *str1;
char *str2;
(중략...) 일 때,
str1 = str2; 와 같은 선언이 얼마나 위험한지를 삽질을 통해 몸소 깨달았다.
두개의 포인터가 동시에 같은 주소를 가리키게 하는 일은 최대한 지양해야겠다.
내 생각보다 디버깅을 하면서 배우는게 참 많은거 같다.
'Logs > 학습 log' 카테고리의 다른 글
2022.02.04. gnl refactoring - 완료! (0) | 2022.02.04 |
---|---|
2022.02.03. gnl 메모리 이중 할당해제, KO 케이스들 (0) | 2022.02.03 |
2022.02.01. gnl & lldb (0) | 2022.01.29 |
2022.01.27. gnl (0) | 2022.01.27 |
2022.01.26. gnl과제 하는 중... (0) | 2022.01.26 |