[libft] 의견이 나뉘는 항목들에 대한 이야기
•
제 주관이 큰 주제고 부족한 부분도 많아 틀린 부분이나 다른 생각에 대해 부담없이 알려주세요!
해결 된 항목
1) ft_atoi
본 과제를 진행함에 있어 범위를 책정하는데 크게 unsigned long long 자료형을 가지는 변수를 사용 하는 부류와 int , unsigned int 을 이용해 int 범위 까지만 처리하는 두 부류로 나뉘는 현상을 볼 수 있었습니다.
applie open source 의 atoi 설명을 확인하면 , atoi의 오버플로우는 별도로 처리되는 게 아니라 strtol 이라는 string to long 함수를 기반으로 사용되기 때문에 int를 넘어서는 범위는 long 범위까지 오버플로우 된 상태로 출력이 되고, long 범위를 넘어설 때는 (0) 언더플로우 또는 오버플로우 (-1) 을 출력하게 된다고 나와있습니다.
이 부분에 대한 해석은 개인차가 있겠지만 저는 오버플로우 처리에 대한 부분을 undefined behavior로 판단하였고 libft 의 목적은 내장함수과 완전히 동일한 함수를 만드는것이 아닌 원본을 정체성을 잃지 않는 범위내에서 나만의 정적 라이브러리를 만드는것이라 생각하고 unsigned int 까지 처리 할 함수가 필요하다면 atoi가 아닌 atoll 또는 그에 준하는 함수를 요구하지 않았을까 하여 atoi의 본래 목적인 int 범위까지만 처리 하는 방향으로 진행하였습니다.
int ft_atoi(const char *nptr)
{
int sign;
unsigned int i;
unsigned int num;
i = 0;
sign = 1;
num = 0;
while (nptr[i] == ' ' || (nptr[i] >= 9 && nptr[i] <= 13))
i++;
if (nptr[i] == '-' || nptr[i] == '+')
{
if (nptr[i] == '-')
sign *= -1;
i++;
}
while (nptr[i] && nptr[i] >= '0' && nptr[i] <= '9')
num = num * 10 + nptr[i++] - '0';
if (sign == -1 && num > 2147483648)
return (0);
if (sign == 1 && num > 2147483647)
return (-1);
// 이 부분에 대해선 테스터기 KO가 뜨는게 보기 싫어 넣어준 코드인데
// 없어도 상관없는 것 으로 알고 있습니다! 어떻게 보면 int범위만 처리하되
// LONG_MAX MIN 테스트 때문에 짜여진 괴상한 짬뽕코드가 되었습니다 (__)
return (num * sign);
}
Plain Text
복사
평가를 하며 unsigned long long 범위를 사용하신분이 있으시면 어떠한 생각으로 그렇게 작성하셨는지 의견을 나눠보고 싶었는데 한분도 뵙지 못해서 저의 의견만 이렇게 남기게 되었습니다, 자유롭게 댓글 남겨주세요!
2) 널가드
널가드가 필요한 함수들, 해야 될까 말아야 될까?
C 89 기준 널가드를 하지 않아도 사용자 혹 개발자가 유효한 값을 넣는 다고 생각해서 널가드를 넣지 않는게 더 정확하다고 볼 수 있습니다. 널가드를 넣는다면 그만큼 함수 내에서 처리 할 것 이 하나 더 늘어난 다는 단점도 있죠. 하지만! 저는 널가드가 필요한 부분에 최대한 가드를 해주었는데 그 이유는 제가 유효한 값만 넣을 자신이 없었기 때문 입니다. 코드를 작성한지 오래된 경우 전체적인 flow는 기억나도 이 변수 왜 줬더라? 하고 까먹는 것 처럼 유효한 범위에 대해 까먹을까봐 가드를 해준 것 이죠 열심히 해서 복기도 잘하는 개발자가 되고 싶습니다 (_ _)
3) ft_substr
프로토 타입 char *ft_substr(char const *s, unsigned int start, size_t len)
지정된 원본 문자열 *s, 시작위치 start, 복사 길이 len을 가지며
ft_substr(”hello 42world”, 6, 3); // 결과는 42w 와 같이 사용하는 함수 입니다. 다만 이 함수의 len 관련해서 널가드 문제와 비슷한 유효한 범위값에 대한 이슈가 하나 있는데 ft_substr(”hello 42world”, 6, 999); 이런식으로 len을 크게 잡아버리면 42world 이후 부분은 len이 999 될때까지 빈 공간이 되어 공간 낭비를 하게 됩니다. 널가드 때와 비슷하게 사용자 혹은 개발자가 적당히 유효한 값을 준다면 상관없겠지만 , 유효범위나 함수에 대한 이해가 없다면 위의 예시와 같은 일이 발생할 수 있고 널가드 이슈와 같은 논리로 저의 성향은 다소 느려져도 안정적인것을 선호 하기 때문에 이 부분에 대한 처리를 해줬습니다.
char *ft_substr(char const *s, unsigned int start, size_t len)
{
char *copy;
size_t i;
size_t j;
i = 0;
j = 0;
if (!s)
return (NULL);
if (len > ft_strlen(s))
len = ft_strlen(s);
// 이 부분 입니다. 저는 len이 s의 길이보다 길면 s의 길이에 맞춰서 공간 낭비를 최소화 하는식으로 처리 // 하였는데 효율측면에서 보면 if문이 하나 더 들어가는것이니 성능면에선 상대적으로 떨어질 수 있겠죠?
// + 저는 단순히 길이만 대입해서 평가를 받았는데 글 작성하면서 보니 길이-시작지점을 해주는게 더 적합해보입니다!
copy = malloc(sizeof(char) * (len + 1));
if (!copy)
return (NULL);
while (s[i] != '\\0')
{
if (i >= start && j < len)
{
copy[j] = s[i];
j++;
}
i++;
}
copy[j] = '\0';
return (copy);
}
Plain Text
복사