[42Seoul] libft - Memory 관련 함수

skyju·2022년 4월 14일
1

libft

목록 보기
1/3

Memory 관련 함수

bzero

0x00의 값을 s영역에 n만큼 초기화한다. (0으로 채운다)

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

	tmp = s;
	i = 0;
	while (i++ < n)
		*tmp++ = 0;
}

memset

bzero 보다 memset사용이 권장된다.
c의 값을 b의 영역에 byte단위로 len크기 만큼 채운다.
초기화 대상 값 별도로 지정가능함. (0으로 지정하면 bzero처럼 사용)

void	*ft_memset(void *b, int c, size_t len)
{
	unsigned char	new_c;
	unsigned char	*tmp;
	size_t			i;

	tmp = (unsigned char *)b;
	new_c = (unsigned char)c;
	i = 0;
	while (i++ < len)
		*tmp++ = new_c;
	return (b);
}

calloc

size크기의 변수를 count개 만큼 저장할 수 있는 메모리 공간을 할당한다.
할당된 공간의 값을 모두 0으로 바꾸고 return한다.
count * size의 계산을 하며 size_t범위를 벗어나 overflow가 날 수 있어서
그 경우 NULL을 return한다.

void	*ft_calloc(size_t count, size_t size)
{
	void	*res;

	if (size && count > (size_t) -1 / size)
		return (NULL);
	res = malloc(count * size);
	if (!res)
		return (NULL);
	ft_bzero(res, count * size);
	return (res);
}

memchr

검사할 메모리의 포인터s를 통해 임의의 문자 c를 검색하고,
있으면 그 위치의 포인터를 반환한다.
검사할 영역의 크기가 변수 n으로 들어온다.
문자관련 함수에 strchr함수가 있는데 무엇이 다른지 생각해보자.
(내가 생각한 결과.. 매개 변수 외에는 작동원리에는 다를게 없음)

void	*ft_memchr(const void *s, int c, size_t n)
{
	while (n--)
	{
		if (*(unsigned char *)s == (unsigned char)c)
			return ((void *)s);
		s++;
	}
	return (0);
}

memcmp

메모리 포인터s1과 s2를 n만큼 비교한다.
같으면 0, 다르다면 두 값의 차를 return한다.
(s1이 크면 양수, 작으면 음수)
memchr와 마찬가지로 strcmp과 어떻게 다른지 생각해보자..

void	*ft_memcpy(void *dst, const void *src, size_t len)
{
	size_t	i;

	i = 0;
	if (!len || dst == src)
		return (dst);
	if (!dst && !src)
		return (0);
	while (i < len)
	{
		((unsigned char *)dst)[i] = ((unsigned char *)src)[i];
		i++;
	}
	return (dst);
}

memcpy

src가 가리키는 포인터의 값을 복사하여 len만큼 dst에 붙여넣는다.

void	*ft_memcpy(void *dst, const void *src, size_t len)
{
	size_t	i;

	i = 0;
	if (!len || dst == src)
		return (dst);
	if (!dst && !src)
		return (0);
	while (i < len)
	{
		((unsigned char *)dst)[i] = ((unsigned char *)src)[i];
		i++;
	}
	return (dst);
}

memmove

src의 메모리를 len만큼 복사하여 dst에 붙여넣는다.
메모리의 이동보다는 메모리의 복사에 가깝다.
memcpy와 유사한 동작을 수행하지만, memcpy와는 달리 복사할 대상을 버퍼에 복사하고
해당 위치에 가서 버퍼에 복사된 것을 붙여 넣는 식으로 동작이 구현되어 있어 성능이 살짝 떨어지고 안정성이 좋다.
memcpy의 차이점을 인지하고 있는 것이 좋다!

더하여 dst와 src의 주소를 비교하고 있는 부분은
두 메모리가 겹쳐서 존재하고 있는 경우를 대비하여 나뉘어진 부분으로,
무엇이 더 앞서있나를 판별한 후 해결해주어야 한다!

void	*ft_memmove(void *dst, const void *src, size_t len)
{
	unsigned char	*d_tmp;
	unsigned char	*s_tmp;

	if (dst == src || len == 0)
		return (dst);
	if (dst < src)
	{
		d_tmp = (unsigned char *)dst;
		s_tmp = (unsigned char *)src;
		while (len--)
			*d_tmp++ = *s_tmp++;
	}
	else
	{
		d_tmp = (unsigned char *)dst + (len - 1);
		s_tmp = (unsigned char *)src + (len - 1);
		while (len--)
			*d_tmp-- = *s_tmp--;
	}
	return (dst);
}
profile
https://github.com/skyju

0개의 댓글