memchr?

#include <string.h>

    void *memchr(const void *s, int c, size_t n);

Linux manpage description

: The memchr() function scans the initial n bytes of the memory area pointed to by s for the first instance of c.
Both c and the bytes of the memory area pointed to by s are interpreted as unsigned char.

해석 및 부연설명

: 포인터 s가 가리키는 메모리에서 n바이트만큼 스캔해 c가 가장 처음 나오는 곳의 주소를 반환한다. 이 때 c와 메모리의 값은 unsigned char로 해석된다. 찾지 못한 경우 NULL을 반환한다.

ex)

char	str[] = "abcdefgehijk";
char	c = 'e';
printf("%s\n", (char *)memchr(str, c, (sizeof)str));

코드 실행 결과

efgehijk

리턴값이 void형 포인터라는걸 고려해야한다.

의문점 및 생각해볼점

  1. strchr 함수와의 차이점
  2. n의 크기에 따른 작동

strchr vs memchr

strchrNUL문자를 검사하고, memchr은 그렇지 않다.
그렇기 때문에 memchr은 검색을 끝내기 위한 길이 매개변수를 하나 더 요구하는 것이다.
기능적으로는 두 함수의 차이점이 없으나 memchrNUL문자 검사를 생략하기때문에 조금 더 빠르다고 한다.
그 외에 문자열의 특정 부분까지만 검사하고싶을 때는 memchr이 필요할 것 같긴 하다.


n의 크기별 반환

  1. n이 s의 길이보다 작을 경우에는 평범하게 작동한다.
  2. n이 s의 길이보다 클 때는 찾는 문자가 s 내에 없을 경우 Segmentation fault가 뜬다.
    n번동안 c에 해당하는 문자를 찾을때까지 계속 메모리 주소를 키워가며 검색하는데, NUL에서 자동으로 멈추는 strchr과는 달리 s가 할당되어있는 메모리를 지나도 멈추지 않기 때문이다.

ft_memchr 구현

void	*ft_memchr(const void *str, int value, size_t size)
{
	while (size-- > 0)
	{
		if (*(unsigned char *)str == (unsigned char)value)
			return ((void *)str);
		str++;
	}
	return (NULL);
}

참고로 memchrconst void *형으로 받고 void *형을 반환하는데서 문제가 생길 수 있다.
memset과는 달리 단순히 str과 value값을 비교하는 것이므로 value값을 반드시 unsigned char형으로 형변환 해주어야한다.