Unborn 8.0 Yellow Pointer
본문 바로가기
42 SEOUL/0_Libft

[Libft] Part1 : bzero, memset, memcpy, memmove, memchr, memcmp

by 에삐니 2022. 3. 25.
728x90

[이전 글]

 

[Libft] 나만의 첫 번째 라이브러리

1. 프로젝트 소개 C 프로그래밍을 할 때 매우 유용한 표준 함수들을 사용할 수 없다면 굉장히 지루할 거예요. 이 프로젝트를 통해 이러한 표준 함수들을 구현하고, 이해하고, 어떻게 사용하는지

bini-079.tistory.com

[다음 글]

 

[Libft] Part2 : Additional functions

삐니의 소소한 일상 [Libft] Part2 : Additional functions 본문 42 SEOUL/Libft [Libft] Part2 : Additional functions 에삐니 2022. 3. 24. 01:22 Prev 1 2 3 4 5 6 7 8 ··· 103 Next

bini-079.tistory.com


Part1 : Libc functions

아래의 함수들을 다시 구현하세요. 이 함수들은 외부 함수를 필요로 하지 않습니다 :

  • isalpha, isdigit, isalnum, isascii, isprint
  • bzero, memset, memcpy, memmove, memchr, memcmp
  • strlen, strnstr, strlcpy, strlcat, strchr, strrchr, strncmp
  •  toupper, tolower, atoi

다음의 함수들은 외부 함수 malloc을 사용하여 구현하세요 :

  • calloc, strdup
반응형

ft_bzero

void	ft_bzero(void *s, size_t n)
{
	size_t			i;
	unsigned char	*str;

	str = (unsigned char *)s;
	i = 0;
	while (i < n)
		str[i++] = 0;
}
  • s을 n크기만큼 0으로 초기화하는 함수이다.
  • 이 함수는 더 이상 사용되지 않는다. memset을 사용한다.
  • size_t : 이론상 가장 큰 사이즈의 unsigned 데이터 타입

 

ft_memset

void	*ft_memset(void *ptr, int value, size_t len)
{
	size_t			i;
	unsigned char	v;
	unsigned char	*p;

	i = 0;
	v = (unsigned char)value;
	p = (unsigned char *)ptr;
	while (i < len)
		p[i++] = v;
	return (p);
}
  • ptr 가 가리키는 메모리 주소부터 len 바이트만큼 value값을 채운다.
  • int로 받는 value는 함수 내부에서 unsigned char로 자동 변경된다.

memset()과 bzero() 모두 unsigned char로 캐스팅하는 과정이 있다.

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

  • unsigned char는 모든 bit를 투명하게 볼 수 있는 특성을 제공한다.
  • 임의의 메모리에 바이트 단위로 접근해 값을 다룰 때에는 반드시 unsigned char를 사용해야 full portability를 얻을 수 있다.
  • signed char 가 표현할 수 있는 값의 개수보다 unsigned char 가 표현할 수 있는 값의 개수가 많다
  • 표준이 바이트 값에 접근해야 하는 경우나 문자에 접근해야 하는 경우 (예: mem(), str() 함수들) 에는 모두 unsigned char로 접근하도록 요구하고 있다.

 

ft_memcpy

void	*ft_memcpy(void *dst, const void *src, size_t n)
{
	size_t			i;
	unsigned char	*dst_temp;
	unsigned char	*src_temp;

	if (!dst && !src)
		return (0);
	dst_temp = (unsigned char *)dst;
	src_temp = (unsigned char *)src;
	i = 0;
	while (i < n)
	{
		dst_temp[i] = src_temp[i];
		i++;
	}
	return (dst);
}
  • src가 가리키는 메모리 주소로부터 n바이트 크기(길이)만큼 dst메모리에 복사한다.
  • 테스터에서 모두 dst, src 모두 null인 경우에는 따로 처리를 해서 null값을 리턴한다.
  • 널 종료 문자(null terminating character)를 검사하지 않는다.(strcpy() 함수와의 차이점)
  • 두 메모리 블록이 겹쳐져 있다면 memmove 함수를 이용해야 한다. (src의 원본 값이 이전 src로 바뀐 상태에서 복사를 해버리기 때문)

void    *ft_memcpy(void *restrict dst, const void *restrict src, size_t n)

  • !! restrict 포인터는 메모리 접근에 관련된 최적화 기능 (C99 표준)으로 42에서는 사용 불가능하다.

Restrict

  • 알맞은 조건이 적용되면, 성능이 비약적으로 증가한다.
  • 포인터가 하나만 가리키고 있다는 것을 컴파일러가 알면, 메모리 복사 없이 비트 연산자를 이용해 연산한다.

 

ft_memmove

void	*ft_memmove(void *dest, const void *src, size_t n)
{
	size_t				i;
	unsigned char		*new_dest;
	unsigned char		*new_src;

	if (dest == src || n == 0)
		return (dest);
	i = 0;
	new_dest = (unsigned char *)dest;
	new_src = (unsigned char *)src;
	if (dest < src)
	{
		while (i < n)
		{
			new_dest[i] = new_src[i];
			i++;
		}
	}
	else
		while (++i <= n)
			new_dest[n - i] = new_src[n - i];
	return (dest);
}
  • src배열은 src와 dest메모리 영역과 겹치지 않는 메모리 영역부터 먼저 복사한다.
    • dst < src : len크기(길이)만큼 src 메모리에서 dest로 복사한다.(memcpy와 동일하다)
    • dst > src : src 마지막 바이트부터 dest + len에 복사한다.

https://hand-over.tistory.com/47 참고

 

ft_memchr

void	*ft_memchr(const void *s, int c, size_t n)
{
	size_t			i;
	unsigned char	find;
	unsigned char	*new_s;

	if (!s)
		return (NULL);
	find = (unsigned char)c;
	new_s = (unsigned char *)s;
	i = 0;
	while (i < n)
	{
		if (new_s[i] == find)
			return ((new_s + i));
		i++;
	}
	return (0);
}
  • s 주소에 접근하여 n만큼 탐색하여 c값을 찾는다.
  • c를 찾으면 그 주소 값을 반환하고 못 찾으면 null을 반환한다.

 

ft_memcmp

int	ft_memcmp(const void *b1, const void *b2, size_t n)
{
	size_t			i;
	unsigned char	*s1;
	unsigned char	*s2;

	i = 0;
	s1 = (unsigned char *)b1;
	s2 = (unsigned char *)b2;
	while (i < n)
	{
		if (s1[i] != s2[i])
			return (s1[i] - s2[i]);
		i++;
	}
	return (0);
}
  • s1과 s2를 n바이트만큼 비교하는 함수이다.
  • 두 포인터가 모두 0이거나 비교하는 길이가 0이면 0을 반환한다.
  • 값이 다르면 그 값의 차이를 반환하고, 값이 같으면 0을 반환한다.
  • strcmp와 같은 논리이나, (unsigned char *) 형을 사용한다는 차이가 있다.

 

728x90
반응형

댓글