━━━━ ◇ ━━━━
-/42

[42] libft

libft를 구현하면서 알아야 할 필수 개념들

libft를 구현하면서 새롭게 배운 개념들에 대해서 정리한다. 각 함수에 대한 설명은 잘 정리된 곳이 많아 생략했다.

Makefile Relink

리링크라고 함은 의존성이 변경되었을때만 타겟을 생성하는 것을 말한다. 의존성이 변경되지 않았다면 리링크되지 않아야 한다. 사실 무리넷은 보너스에 대한 리링크는 잡지 않는 것 같지만, 알고있어야 할 것 같아서 정리해본다.

bonus: $(OBJ_B)
    $(AR) $(TARGET) $^

위 코드는 OBJ_B가 존재한다면 TARGET을 생성한다. OBJ_B가 변경되었나를 체크하지 않기 때문에 make bonus를 하면 무조건 리링크되게 된다.

ifdef WITH_BONUS
    OBJ = $(OBJ_O) $(OBJ_B)
else
    OBJ = $(OBJ_O)
endif
...
bonus:
    make WITH_BONUS=1 all

위 코드는 make bonus를 하면 WITH_BONUS라는 상수를 1로 지정하여 코드를 실행한다. WITH_BONUS라는 상수가 1일때는 OBJOBJ_OOBJ_B 모두의 변경사항을 체크하기 때문에 리링크가 방지된다.

Null Protection

Null아무런 값이 없는 값을 뜻한다. 이는 불분명한 값에 들어갈 수 있는 값을 표현해줄 수 있다는 이점이 있지만, 이는 값을 사용하는 쪽에서 수많은 오류를 발생시긴다.

public String getStudentID(Student student){
    return student.getUniveristy().getStudentId();
}

위의 코드는 자바로 작성된 코드이다. 해당 코드에서 NPE (Null Pointer Exception)이 발생할 수 있는 경우는 다음과 같다.

  1. student가 null일 경우
  2. student의 university가 null일 경우
  3. student의 university의 studentId가 null일 경우

이렇게 간단한 코드 하나에도 null로 인한 문제가 빈번하게 발생한다. libft에서도 null에 대한 처리를 할 것인지, 아니면 터지도록 놔둘것인지에 대한 선택지가 존재한다.

사실 나는 터지게 함으로써 어디서 에러가 났는지를 확인하는것이 맞다고 생각하여 not-protect하였는데, 조금 찾아보다 보니 protect 하는것이 더 좋을것이라는 생각이 들었다. 그 이유는 다음과 같다

  1. 기본적으로 protect를 하지 않게되면, null이 들어왔을때 프로그램이 도중에 실행중단된다. 다시말해서, 의도치 않은 값이 들어왔을때 프로그램이 의도치 않게 중단되면서 발생할 수 있는 여러가지 위험요소들이 존재하는 것이다.
  2. 디버깅 면에서도 null이 들어왔을때는 null을 반환하는 식으로 프로그래밍 하면, 값을 바꾸어가면서 파고파고 들어가는 식의 디버깅이 가능하지만, protect하지 않으면 실행중단이 되어버리므로 그러한 디버깅이 불가능하다. null이 들어왔을때는 null을 반환해버리는 자바스크립트의 편리성만 보아도 null protection이 얼마나 소중한지 알 수 있다.

반복문에서의 메모리 해제

반복문에서 메모리 해제는 필수적이다. ft_split에서 도중에 malloc을 실패하여 리턴한다고 하면, 지금까지 malloc한 메모리들을 해제해줘야 메모리 누수를 막을 수 있다.

while (i < ft_strlen(s))
{
    //split의 기준이라면 그냥 스킵하고
    if (s[i] == c)
        i++;
    //그게 아니라면 한 단어를 복사하여 결과 array에 넣는다.
    else
    {
        //만약 한 단어의 복사가 잘 이루어지지 않아 반환해야 한다면
        if (!(temp = ft_malloc_tmp(s, &count, c, i)))
        {
            //지금까지 복사된 단어들을 모두 free해주어야 한다
            while(result*)
                free(result++)
            return (NULL);
        }
        result[count_r++] = ft_memcpy(temp, s + i, count);
        i += count;
    }
}
COMMENT
1