서론
42서울 두 번째 과제인 get_next_line에 대한 기록을 남겨 놓으려고 한다. gnl은 fd(파일 디스크립터) 값을 인자로 받아서 파일을 읽고 개행문자 '\n' 단위로 문자열을 잘라서 리턴하는 함수를 구현하는 과제이다. C의 파일 입출력, 정적 변수, 메모리 누수 방지 등에 대한 내용을 배울 수 있는 과제인 것 같다.
본 과제에서는 C의 static 변수(정적 변수)를 하나 사용할 수 있다. 정적 변수는 fd 값에서 버퍼 사이즈만큼 읽은 문자열에서 '\n'을 기준으로 문자열을 반환하고 남은 문자열을 저장하는 데 사용된다.
구현
get_next_line
- backup == 0이라면 정적 변수 backup에 공백 문자열을 할당받는다.
- 버퍼 사이즈만큼 buf에 동적할당받는다.
- gnl_read_line 함수로 개행문자가 나오기 전까지 fd 값으로 파일을 읽어서 backup에 저장한다.
- gnl_get_line 함수로 backup에서 리턴할 문자열을 추출한다.
- gnl_update_backup 함수로 backup에서 리턴할 문자열(line 변수)만큼을 제거해서 backup를 업데이터 한다.
gnl_read_line
- fd 값으로부터 BUFFER_SIZE만큼 buf에 문자열을 읽어서 저장한다.
- read로 읽어온 buf 문자열의 끝에 '\0'를 넣는다.
- backup 뒤에 buf를 연결한다.
- 새로 읽은 buf 안에 개행문자('\n')가 있으면 backup을 리턴한다.
처음에 buf[BUFFER_SIZE] = '\0';이라고 코드를 첬는데 이것 때문에 에러를 못 찾아서 엄청 고생했다. read 함수는 buf에 문자열을 읽어올 때 맨 뒤에 공백 =문자('\0')를 붙여주지 않아서 직접 붙여줘야 하는데, 만약 버퍼 사이즈가 100이고 read 함수에서 10만큼만 문자열을 읽어오는 경우에 buf[BUFFER_SIZE] = '\0'를 해버린다면 buf[11~100]에는 잘못된 값들이 들어갈 수도 있게 된다. 그러니 이 글을 읽는 카뎃들은 처음부터 공백문자를 올바른 위치에 두도록 하자.
tip
구현하다 보면 함수의 line 제한(25줄)이 빡빡할 수 있다. 공백 문자열이 필요할 때 strjoin("", "")를 활용하자. 동적할당 + 문자열 초기화 최소 두 줄이 필요한데 한 줄로 줄일 수 있다.
추가로 Libft를 구현할 때 구현했던 함수 중에 쓸만한 함수들이 많으니 복사 붙여 넣기 해서 get_next_line_utils.c 파일에 넣고 사용하자. 변형하지 않고도 구현이 가능하지만 line 제한 맞추기가 힘들면 변형해 보자.
메모리 누수(leak) 잡기
먼저 메모리 누수 검사를 위하여 다음 코드를 사용하자.
f(void)
{
system("get_next_line leaks");
}
int main(void)
{
atexit(f)
// gnl 테스트 코드
}
gnl 테스트를 위한 메인 함수이다. 주석 부분에는 gnl 테스트 코드를 작성하자.
leaks는 메모리 누수를 검사하는 유틸리티로, get_next_line(프로그램 이름을 이걸로 해야 함) 실행 후 메모리 누수가 있는지 검사한다.
atexit 함수는 프로그램 종료 시점에 호출되는 함수이다. 이 함수로 프로그램 종료 시 f()를 호출한다.
tip
gnl을 구현할 때 함수를 다 구현하고 테스트를 돌리지 말고 조금씩 구현할 때마다 테스트를 돌리는 것을 추천한다. 그렇지 않으면 구현하는 시간보다 오류 잡고 leak 잡는 시간이 더 오래 걸릴 수도 있다. 오류가 없는지 테스트를 잘하고 테스트할 때 메모리 leak이 없는지까지 잘 테스트해 준다면 쉽게 과제가 끝날 수 있다.
코드를 구현할 때에는 아래 사항들을 주의해서 구현하자.
- strjoin 사용 후 인자로 사용했던 문자열 free 했는지 확인하기
- 함수 내에서 동적할당받은 변수를 가능하면 함수 종료 전에 free 하기
- Libft 함수 사용 시 잘못 구현했다면 해당 함수에서 발생하는 메모리 누수 주의하기
- 다른 함수를 호출해서 동적할당을 받았다면 잘 free 해주기
- malloc 사용 이후 항상 free 사용할 부분 생각해 두기
- 다른 함수에서 free 할 때 참조(&)를 사용해서 변수 원본을 free 해주기
- 이중 free 하지 않도록 주의하기
'대외활동 > 42서울' 카테고리의 다른 글
[42서울] so_long 그래픽, mlx 라이브러리 (0) | 2024.08.11 |
---|---|
[42서울] so_long 맵 유효성 검사(BFS) (0) | 2024.07.22 |
[42서울] ft_printf 구현 (한 문장으로 구현하는 이진수 보수 연산) (0) | 2024.06.21 |
[42서울] Libft 함수 정리와 후기 (0) | 2024.03.20 |
[42서울] push_swap 그리디 알고리즘 (2) | 2024.03.04 |