[Libft] Part 1

libft 프로젝트의 part1 함수들을 구현하면서 메모했던 내용들을 정리해두었다. 이 라이브러리의 함수들은 꾸준히 업데이트 되고 있기 때문에 가장 최신의 코드는 여기 깃허브 저장소를 참고...

libft 프로젝트의 part1 함수들을 구현하면서 메모했던 내용들을 정리해두었다. 이 라이브러리의 함수들은 꾸준히 업데이트 되고 있기 때문에 가장 최신의 코드는 여기arrow-up-right 깃허브 저장소를 참고...

1. ft_memset

    #include "libft.h"

    void        *ft_memset(void *dest, int c, size_t n)
    {
        unsigned char   *new_dest;
        unsigned char   src;
        size_t  i;

        new_dest = dest;
        src = c;
        i = 0;
        while(i++ < n)
            *new_dest++ = src;
        return (dest);
    }

dest 위치부터, n개의 바이트 만큼, c 라는 값으로 초기화 하는 함수.

  • 이 때 초기화 할 값인 c는 인자로는 int로 전달되지만 함수 내부적으로는 unsigned char로 형변환 되어서 사용된다.

    메모리에 접근할 때에는 signed char형이 아닌 unsigned char형을 사용해야하는 이유

    unsigned char 는 모든 bit를 투명하게 볼 수 있는 특성을 제공합니다. 즉, 다른 type 은 내부 비트의 일부를 값을 표현하기 위한 용도가 아닌 다른 용도(부호 비트)로 사용할 수 있으나 unsigned char 는 이것이 허락되지 않습니다.

    따라서, 임의의 메모리에 바이트 단위로 접근해 값을 다룰 때에는 반드시 unsigned char 를 사용해야 full portability 를 얻을 수 있는 것입니다. 또한, 그와 같은 이유로 signed char 가 표현할 수 있는 값의 개수보다 unsigned char 가 표현할 수 있는 값의 개수가 많다는 사실에도 유의할 필요가 있습니다. signed char <-> unsigned char 사이의 값 변환이 1:1 로 이루어질 수 "없는" 경우도 있음을 의미합니다.

    이런 이유로, 표준이 바이트 값에 접근해야 하는 경우나 문자에 접근해야 하는 경우 (예: mem(), str() 함수들) 에는 모두 unsigned char 로 접근하도록 요구하고 있습니다.

    출처 : https://kldp.org/node/75686arrow-up-right

  • 그리고, 바이트 단위로 초기화 하기 때문에 int형 배열을 초기화 할 때는 주의해야 한다.

    예를 들면 ft_memset(arr, 1, sizeof(arr))을 호출하면 arr 배열이 모두 1로 초기화 된다고 생각하는데, 실제로는 배열이 모두 16843009로 초기화 된다. 16843009의 2진수 표현은 0001 00000001 00000001 00000001 이다. 즉, arr 배열은 1바이트(8비트)당 1로 초기화 된 것이다. 바이트가 딱 떨어지게 초기화 되지 않기 때문에 int형 배열의 요소를 1로 초기화 할 수 없다. 다른 정수도 모두 마찬가지다. 딱 4개의 값만 가능하다고 한다. 0, -1, 0x3f, 0x7f.

    출처 : https://blog.naver.com/chogahui05/221484049429arrow-up-right

  • size_t 자료형은 '이론상 가장 큰 사이즈를 담을 수 있는 unsigned 데이터 타입'으로 정의된다.

2. ft_bzero

b 위치부터, n개의 바이트 만큼 0으로 초기화 하는 함수.

  • 이 함수는 더 이상 사용되지 않는다. memset을 사용하자.

3. ft_memcpy

  • src 가 가리키는 곳 부터 n 바이트 만큼을 dest 이 가리키는 곳에 복사한다.

  • 이 함수는 source 의 널 종료 문자(null terminating character) 을 검사하지 않는다. 언제나 정확히 num 바이트 만큼을 복사한다.

  • 만일 두 메모리 블록이 겹쳐져 있다면 memmove 함수를 이용해야 한다. src의 원본 값이 이전 src로 바뀐 상태에서 복사를 해버리기 때문이다.

  • const void* src를 함수 내에서 unsigned char *로 강제 형변환을 하려고 했더니 경고가 떴다. const char 타입으로 받은 인수를 그냥 char 타입으로 다른 변수에 넘겨주려할 때 발생하는 경고라고 한다. 즉 const라는 qualifier(수식어,한정어)가 떨어져 나갔다는 뜻. const unsigned char *로 형변환 해줘야 함.

4. ft_memccpy

  • n바이트의 데이터를 dest에 복제할 때에 src 데이터에서 문자 c를 만나면 c까지 복제하고 복제를 중단한다.

  • 복제된 dest변수에서 복제가 끝난 다음 번지를 return 한다. 만약 문자 c를 만나지 않았다면, n바이트를 복제하고 NULL을 return 한다.

  • 의문점

    강제 형변환에 대해서.

    형변환을 명시적으로 써주지 않으면 워닝이 뜬다? → const 변수에 대해서만 그런걸로. gcc -Wall 플래그를 설정하면 에러로 처리해 컴파일이 되지 않는다.

5. ft_memmove

memmove 사용법 및 구현 - C 메모리 이동arrow-up-right

src메모리 영역에서 dest 메모리 영역으로 n 바이트 만큼 복사한다. 이 때, src 배열은 src와 dest의 메모리 영역과 겹치지 않는 메모리 영역부터 먼저 복사한다.

  • 메모리 영역이 overlap 되는 경우

    사실 잘 상상이 안됐었는데...

    1. 한 배열 안에서 복사를 수행할 때

    2. 그러면서 src 시작 주소가 dest 시작 주소보다 앞에 있을 때

      오버랩의 가능성이 생긴다.

  • overlap 해결 방안은?

    src의 마지막 주소 -> dest의 마지막 주소, 즉 뒤에서 부터 한 바이트 씩 복사한다.

6. ft_memchr

메모리 블록에서의 문자를 찾는다.

ptr 이 가리키는 메모리의 처음 num 바이트 중에서 처음으로 value 와 일치하는 값의 주소를 리턴한다.

  • 메모리 블록에서 value 와 일치하는 값이 있다면 그 곳의 주소를 리턴하고 값을 찾지 못한다면 NULL 을 리턴한다.

  • 의문점 1

    컴파일 시 이런 경고가 떠서 return 값을

    이렇게 바꿨더니 해결됐다.

    혹은 아래 처럼 선언부에서 const 한정자를 사용하지 않아도 해결된다.

    참고 : https://igotit.tistory.com/entry/char-const-char-char-constarrow-up-right

  • 의문점 2

    반환형이 void 면 반환할 때 다시 void 로 형변환을 한 뒤에 반환해야 하나? malloc에서는 안그랬던 것 같은데...

    https://pang2h.tistory.com/253arrow-up-right

  • 인덱스로 표현하는 게 가독성이 더 좋을 것 같아서 수정함.

7. ft_memcmp

ptr1 이 가리키는 처음 num 바이트의 데이터와 ptr2 가 가리키는 처음 num 바이트의 데이터를 비교한다.

8. ft_strchr

문자열에서 특정 문자를 찾을 때 사용하는 함수.

  • 문자열 s에서 첫 번째로 찾은 문자 c의 포인터를 리턴한다.

  • 만일 찾는 문자가 없다면 NULL포인터를 리턴한다.

  • 이 때 마지막 NULL 문자도 C 문자열의 일부로 간주하기 때문에 이 함수는 문자열의 맨 끝 부분을 가리키는 포인터를 얻기 위해 사용할 수 도 있다.

  • int c는 검색할 문자로, int 형태로 형변환 되어서 전달되지만 함수 내부적으로는 다시 char 형태로 처리된다.

9. ft_strrchr

문자열 s에서 마지막으로 있는 문자 c의 포인터를 리턴한다.

  • 예외처리

    s가 빈문자열일 때, s의 첫 글자만 c일 때 NULL이 아니라 s의 첫글자를 반환해야 함.

10. ft_strnstr

문자열을 검색한다.

  • len 이하의 big 에서 little 를 검색하여 가장 먼저 나타나는 곳의 위치를 리턴한다.

  • 이 때 일치하는 문자열이 없다면 널 포인터를 리턴하게 된다.

  • 검색에서 마지막 널 문자는 포함하지 않는다.

  • core dumped 에러

  • 남은 size의 길이가 l_len 길이 보다 작다면, 비교할 의미가 없으므로 NULL을 리턴

11. ft_strncmp

  • 의문점

    return 할 때 unsigned char로 형변환 하는 코드를 봤다. 필요한가?

    • 2020.03.10 해결

      ft_strncmp("test\200", "test\0", 6) 같은

      128 이상의 아스키코드 수도 계산하기 위해서 unsigned char *로의 형변환이 필요했다.

12. ft_atoi

13. ft_isalpha

연산자도 참(1)과 거짓(0)을 반환한다.

14. ft_toupper

15. ft_calloc

  • size 크기의 변수를 nmemb개 만큼 저장할 수 있는 메모리 공간을 할당한다.

  • 그리고 동적으로 할당한 메모리의 모든 비트를 0으로 설정한다.

  • malloc 과의 차이점은?

16. ft_strdup

  • 문자열 str 길이 + 1 크기를 malloc으로 할당 후 문자열 str을 복사한 후 반환한다.

  • 반환받은 메모리는 반드시 free를 통하여 메모리를 해제해야 한다.

  • malloc + strcpy

Last updated

Was this helpful?