대외활동/42서울

[42서울] get_next_line 구현 (메모리 누수 잡기, 구현 tip)

Campus Coder 2024. 6. 19. 14:44
728x90
반응형

서론

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에 문자열을 읽어서 저장한다.
  • buf 문자열의 끝에 '\0'를 넣는다.
  • backup 뒤에 buf를 연결한다.
  • 새로 읽은 buf 안에 개행문자('\n')가 있으면 backup을 리턴한다.

 

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 하지 않도록 주의하기

 

728x90
반응형