티스토리 뷰

728x90
반응형
틀린 내용이 있다면 댓글로 알려주세요! 감사합니다 :)

TESTER URL 첨부 & 틀린 내용 삭제와 추가적인 내용 삽입

내가 사용한 TESTER들

github.com/lgrellie/gnl_tester

github.com/charMstr/GNL_lover

github.com/DontBreakAlex/gnlkiller

github.com/Mazoise/42TESTERS-GNL

 

0. Program Source

참고로 utils에서 동적 할당이 실패했을 때, protected가 안돼 있는 부분이 있다. ft_strnul 같은 경우와 주석을 참고 바란다.
동적 할당 1을 실패하는 경우가 너무 극단적이라 생각해서 protected를 하지 않았다. Norm에 걸리는 상황이기도 했다. 저는 defense에 성공했지만, 철저하신 분들은 점수를 안주실 수도 있다는 점 염두에 두시길.. 
cos18님의 코드를 보고 공부했으며, 영향을 제일 많이 받았다. 개인적으로 난해하긴 했으나, 항상 새로운 시각과 이해를 하면 굉장히 체계적으로 코드를 짠 것을 알 수 있었다.

1. 선행지식

minsoftk.tistory.com/40

 

open, close, read 함수에 대하여

틀린 내용이 있다면 댓글로 알려주세요! 감사합니다 :) 함수들에 공부하기 전 사전지식 함수들에 공부하기에 앞서 파일디스크립터 라는 개념을 먼저 이해하고 있으면 좋다. 파일 디스크립터(File

minsoftk.tistory.com

기존의 함수들의 역할은 쉽게 알 수 있지만, return값들을 모른다면 어떻게 구현을 해야 할지 감이 잘 오지 않는다. 따라서 fd로 읽어 들이는 함수들의 return 값들을 이해할 필요가 있다. 구현까지는... 힘들지 않을까 싶다.. 

 

2. 이해가 안 가던 부분 

그냥 처음부터 이해가 가지 않았다.... 도대체 어떻게 구현을 해야 하는가... 역시 감도 안 잡힐 때는 slack이 최고다..

read(fd, buff, BS); 를 해서 라인을 읽은 다음, buff 안에 개행 문자가 있는지 없는지 검사를 합니다. 그런데 개행 문자가 있는지 검사하기 전에 우선 함수 내부에 static char * 변수를 선언해서 지금까지 읽은 라인을 백업한 다음 개행 문자가 있다면 다음단계로 넘어가고, 아니라면 개행문자가 있을 때까지 읽고 또 읽어요(이 과정에서 기존에 백업한 것과 계속 합쳐나가야합니다) 개행문자가 있다 -> 그다음 단계는 static char *에 있는 애들을 \n 전과 후로 잘라서, \n 전까지는 line 에다가 주고 나머지는 다시 static 변수에 백업.... 하면 됩니다.

@wpark 님의 slack 글이다.

처음엔 이게 무슨 말인지도 이해가 잘 안 갔다... 따라서 이해를 하면서 필요한 사전 지식들을 아래와 같이 정리해봤다.

 

왜 line을 이중 포인터로 받는가?

int main(void)
{
	char *line = 0;
	int ret;
	int fd;
	fd = open("your_file_name", O_RDONLY);
	while ((ret = get_next_line(fd, &line)) > 0)
	{
		printf("%s\n", line);
		free(line);
	}
	printf("%s\n", line);
	free(line);
	return (0);
}

위의 예시를 보면 명확하게 이해를 할 수 있다. 위의 예시는 main에서 get_next_line 함수를 test 하기 위한 예시이다. 이중 포인터로 쓴 이유는 char 포인터 변수인 line에 값을 전달하기 위함이다. 위의 코드에서 while문 부분을 살펴보면 만약 &line이 아닌 line을 넘긴다면 gnl함수 안에서 개행 `\n`을 찾았을 때,  gnl함수가 끝나면 값은 저장되지 않고 사라지기 때문이다. 따라서 주소 값을 넣어서 gnl에서 line에 값을 전달하기 위함이다. 

정확하게는 Call by reference를 이용하기 때문이다.

m.blog.naver.com/daum7766/221673227186

 

Call by value(콜 바이 벨류), Call by reference(콜 바이 레퍼런스), Pass by reference(패스 바이 레퍼런스)란?

Call by value란?매개변수를 주어진 값을 복사하여 전달하는 방식으로 메소드 내에서 변경한 값은 메소드 ...

blog.naver.com

위 포스트에서 자세한 내용을 설명하고 있으니 참고 바란다.

즉, main문에서 보듯이 char *line를 인자로 집어넣게 되니 &line으로 파라미터를 넘기게 되는 것이다. 그렇다면 아래와 같은 프로토타입이 만들어지는 것을 이해할 수 있을 것이다.

int		get_next_line(int fd, char **line)

 

get_next_line에서 개행 전까지의 출력을 어떻게 시켜줘야 하는가?

어떻게 보면 굉장히 기본이 부족한 의문일 수 있지만, 처음에 입력된 문자열들의 출력을 어떻게 해줘야 하나 궁금했다. 내가 사용할 수 있는 함수 중에 write는 없었기 때문이다. 그래서 출력을 어떻게 하는 거지...?라는 고민을 했지만 생각해보니 개행 전까지의 문자열을 get_next_line의 파라미터인 line에 값을 전달해서 line에 전달된 값을 main에서 printf 하는 방식으로 test가 된다는 것을 이해했다. 위의 예제 코드를 보면 line에 입력을 받은 뒤 printf 해주고 나서 free를 해준다. 

그렇다면 여기서 free를 왜 해주는지 또 의문이었다. 이는 동적 할당한 메모리를 동적 해제해주는 함수인데 line을 왜  free 해주는 걸까?라는 의문이 있었다. 그런데 조금만 생각해보니 너무나 당연했다. free를 해주는 이유는 get_next_line안에서 개행을 찾을 때, 동적 할당을 통해 문자열을 나누기 때문에 그에 대한 메모리 누수를 막기 위해  free를 해준다. 

즉, 개행 전까지의 문자열을 line에 넘겨야 하는데 기존의 원본은 저장을 하고 있어야 하기 때문에 문자열을 복사해야 한다. 이 과정에서 동적 할당이 무조건 사용이 되는데, 이를 해제하기 위한 것이라고 생각하면 된다.

예를 들어 "abcd\nefg"라는 문자열을 나누기 위해 ft_strdup이나 ft_substr을 이용할 수 있을 텐데, 이 과정에서 동적 할당이 발생하지만 함수가 끝나지 않기 때문에 free를 해주지 않으면 메모리 누수가 발생한다. 메모리 누수에 대해서도 자세한 이해도가 없기에 메모리 누수에 대한 내용도 찾아봤다. 

 

 

c언어 free 함수 : 쌍이 맞아야 된다.

 동적 할당은 무엇인가요? 예를 들어, 이런 코드가 있다고 해 봅시다.  malloc 함수가 호출되기 전에 메모리 상태는 아래와 같습니다.  처음에 Heap 영역에는 아무 것도 할당되지 않았습니다. 그런

codingdog.tistory.com

동적할당 후엔 free로 동적할당 해제를 해주어야 된다는 내용의 포스트다. 한번 확인해보자

 

valgrind C언어 메모리 누수 찾기

며칠전에 서버 관리자로부터 이메일이 왔습니다. 관리자한테서 연락이 오는건 흔한일이 아닌데요.ㅋ 내가 담당하는 프로세스가 시간이 지날수록 메모리를 계속 누적하고 있다는 거에요. ^^;; 갑

sidepower.tistory.com

위의 포스트는 c언어에서 편리하게 메모리 누수를 찾을 수 있는 툴을 소개한다. 참고하길 바란다!

 

3. Buffersize의 최대 크기? 왜 1000000000가 넘어가면 터질까?

buffersize가 커지면 Segmentation fault (core dumped)가 뜬다.

-> 자동 변수는 stack 영역에 저장되는데, 보통 스택 사이즈가 윈도는 1메가, 리눅스는 8메가로 설정되어있다. 만약에char buf[BUFFER_SIZE + 1];라고 선언하고 여기에 스택 사이즈보다 큰 수를 받으면 스택 오버플로우가 생길 수 있다.

 

처음에 gnl을 작성하려고 할 때, 정말 감도 안 잡혔다. 머릿속에서 구상 자체가 힘들었다. 그래서 위에서 도움이 될만한 사전지식에 대해서 이야기를 해봤는데 나처럼 어려운 부분이 많은 분들에게 도움이 된다면 좋겠다. 

본인은 처음에 gnl을 작성하려고 할때, 정말 감도 안잡혔다. 머리속에서 구상자체가 힘들었다. 위에 언급한 것처럼 gnl에서 write를 써서 출력을 시켜야 하는 건가?라는 엉뚱한 생각을 할 정도였으니.. static에 대한 내용도 공부를 하긴 했지만, 맞게 이해했는지도 헷갈렸다. 그러다 결국엔 기존의 기수분들의 코드를 참고하는 방법밖에 없었다. 그런데 이게... 치팅이라는 생각이 강해서 과연 내가 남의 코드를 참고하면서 공부하는 게 맞는 건지 헷갈렸다. 하지만 본인처럼 정말 어떻게 해야 할지 감이 전혀 안 온다 싶으면 남이 짠 코드를 참고하면서 공부해보는 것도 좋은 방법이라고 생각한다. 그래도 모르겠다면 그럴 땐 옆의 동료에게 도움을 구해보자. 

 

 

📕 reference :

velog.io/@hidaehyunlee/GetNextLine-%EC%82%BD%EC%A7%88%EC%9D%98-%EA%B8%B0%EB%A1%9D

728x90
반응형
댓글