[get_next_line] 정적변수, static variable에 대해 알아보자

개발하는 곰댕이·2021년 4월 11일
0

42Seoul

목록 보기
12/45

1. GNL의 꽃 정적변수에 대해 알아보자.

gnl을 끝냈는데 static이 뭔지도 모른다면... 치팅입니다...
그 정도로 정적변수는 gnl에서 중요합니다. 그렇기에 확실하게 짚고 넘어갑시다!

1.1 정적변수는 변수의 자료형 앞에 static을 붙여서 만듭니다.

    ex)
    static int a;

1.2 정적변수는 초기화해 주지 않는다면 딱 한번만 0으로 초기화가 됩니다.

int main(void)
{
	static int num;
    
    printf("%d", num);
}

0

1.3 정적변수는 지역변수처럼 선언된 함수 내에서만 동작하지만 함수가 끝나더라도 사라지지 않습니다.

void my_static(void)
{
    static int num;
    
    num += 1;
    printf("%d\n", num);
}

int main(void)
{
    my_static();
    my_static();
}

1
2

이렇게 동적 할당처럼 함수가 끝나더라도 그 값이 남아있고 그 함수에 다시 들어가면 이전에 있던 값이 그대로 남아있습니다.

1.4 정적변수는 전역변수처럼 프로그램이 시작될 때 메모리에 할당되고, 프로그램이 종료될 때 회수됩니다.

  • 지역변수처럼 함수가 끝나면 회수되지 않고 전역변수나 동작할당처럼 프로그램이 끝날 때 회수됩니다.

1.5 정적변수는 상수로만 초기화가 가능합니다.

  • 일반적인 변수로는 초기화가 안 된다는 뜻입니다. 리터럴 상수로만 된다고 하는데 const변수로 초기화가 되는 것 같아요.

2. GNL! 어떤식으로 동작될까??

  • GNL이 어떤 식으로 동작이 되는지 사진으로 보면서 이해해 보도록 합시다.
    우선은 gnl.txt라는 파일을 읽을거고 그 파일의 내용은 이렇습니다.
get_next_line
123456789

main은 이렇게 사용해서 한 줄씩 읽어들이고, BUFFER_SIZE는 5로 정해놓고 진행하도록 합시다.

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

gnl내부에서 사용되는 변수 buf와 static_buf은 이렇게 선언됐다고 생각해 두고 넘어갑시다.

char *buf[BUFFER_SIZE];
static char *static_buf;

그럼 이제 gnl이 어떻게 동작하는지 간단하게 알아보도록 합시다.
우선 read함수로 BUFFER_SIZE만큼 파일을 읽을겁니다. 그러면 'gnl.txt'의 파일안에 5개의 문자 "get_n"까지만 가지고 와서 buf에 넣어둘 것입니다.

그런 다음에 buf에서 static_buf로 "get_n"을 옮깁니다.

그리고 static_buf에 있는 문자열에 개행이 있는지 확인하는데 없으니 BUFFER_SIZE만큼 한번 더 읽어들이고 static_buf에 이어붙입니다.

개행이 없으니 한번 더 반복합니다.

개행을 찾았습니다! 그러면 개행 전까지의 문자를 매개변수로 들어온 line에 할당한 후 static_buf에는 개행 이후의 문자만 남겨놓습니다.

이런 식으로 우리는 한 줄을 읽어들였고 gnl은 이런 식으로 동작하게 됩니다.

3. 그래서 static을 왜 쓰는건데? 동적할당도 함수가 끝난이후에 쓸 수 있잖아?

gnl함수가 끝나기 전 까지는 일반적인 할당이나 별 차이 없지만 gnl함수가 끝난다면 우린 저장해놓은 "1"이라는 문자열을 찾을 수 없게 됩니다.
무슨 말이냐면 char_buf는 지역변수입니다. 함수가 끝나면 사라지죠.
즉 "1"을 가리키고있던 char_buf가 사라졌으니 우린 "1"을 찾을 수 없게되어 메모리 누수가 나게 됩니다.
gnl을 다시 불러들여서 사용해도 이전에 사용했던 char_buf와 그 다음 char_buf는 전혀 다른 변수가 되어버린 것이죠.

이런 내용때문에 우린 static을 사용할 수 밖에 없습니다.
static은 함수가 끝나도 사라지지 않습니다.
이 말은 함수가 끝날 당시의 static_buf="1"이 한번 더 gnl을 사용해서 들어갔을때도 그대로 static_buf="1"이라는 뜻입니다.
이렇기 때문에 정적변수를 사용해야되는 것이죠.

[get_next_line] get_next_line에 대해 알아보자.
[get_next_line] 파일디스크립터에 대해 알아보자
[get_next_line] 정적변수, static variable에 대해 알아보자
[get_next_line] get_next_line! 어떤 식으로 구현해야할까?

0개의 댓글