memset 함수 구현하기

윤효준·2024년 7월 22일
0

42 Libft 복습

목록 보기
7/28

memset 함수의 manual은 다음과 같다!

Synopsis

#include <string.h>

void	*memset(void *b, int c, size_t len);

void 포인터란???

memset의 첫번째 인자는 void *b이다.
b는 일반적으로 메모리 블록을 가리키는 변수의 이름으로 사용되며, 흔히 block 또는 buffer를 의미한다.
void *는 c언어에서 모든 데이터 타입을 가리킬 수 있는 포인터 타입이다. 특정 데이터 타입에 구애받지 않고 임의의 메모리 주소를 가리킬 수 있는 포인터로 범용성을 위한 포인터이다.

아래의 예시를 보면 이해하기 더 좋을 것이다.

int main() {
    int		i_val = 42;
    double	d_val = 3.14;
    char	c_val = 'a';

    void *ptr;

    // int 타입 변수 가리키기
    ptr = &i_val;
    printf("i_val = %d\n", *(int *)ptr);

    // double 타입 변수 가리키기
    ptr = &d_val;
    printf("d_val = %.2lf\n", *(double *)ptr);

    // char 타입 변수 가리키기
    ptr = &c_val;
    printf("c_val = %c\n", *(char *)ptr);

    return 0;
}

대신 가리키는 변수를 사용할 때는 적절한 타입으로 캐스팅해야 한다.

void 포인터가 필요한 이유

  • 다양한 타입의 데이터를 처리할 수 있는 유연한 함수와 데이터 구조를 만들 수 있다.
typedef struct s_node {
	void			*data;
    struct s_node	*next;
}	t_node; //링크드 리스트, 트리 등의 노드가 다양한 타입의 데이터를 저장할 수 있도록 `void *`를 사용
  • malloc과 같은 동적 메모리 할당 함수는 메모리 블록을 반환하지만, 반환되는 블록의 타입을 미리 알 수 없기에 void *를 사용하여 타입에 관계없이 동적 메모리를 관리할 수 있다.

Description

  • memset함수는 len바이트만큼을 c로(unsigned char로 변환된) 문자열 b에 쓴다.

사용 예시

char buffer[100];
int array[50];

// buffer를 0으로 초기화
memset(buffer, 0, sizeof(buffer));

// array를 -1로 초기화
memset(array, -1, sizeof(array));

Return values

  • 첫 번째 인자인 b를 반환한다.

굳이 반환값을 가질 필요가 있을까 싶지만 아래와 같은 이유로 반환값 b를 가진다!

  • 연속적인 함수 호출
 strcpy(memset(buffer, 0, sizeof(buffer)), "Hello, World!");
  • 일관된 인터페이스
C 표준 라이브러리의 많은 함수들은 입력 포인터를 반환하는 패턴을 따른다.
이는 함수의 일관된 인터페이스를 유지하게 해주며,
개발자가 이러한 함수들을 사용할 때 예측 가능한 동작을 제공한다.

memset 함수의 필요성

  • 직접 루프를 작성하여 값을 설정하는 것보다 memset 함수가 최적화되어 있어 더 빠르다.

  • memset을 사용하여 메모리를 명확히 초기화함으로써 이전에 저장된 임의의 데이터에 의한 예기치 않은 동작을 방지한다.

  • 초기의 컴퓨터 시스템은 메모리 초기화 작업이 자주 필요했으며, 이를 최적화하기 위해 하드웨어 레벨에서 빠르게 수행될 수 있는 함수가 필요했고 이러한 필요에 따라 memset이 최적화된 메모리 초기화 방법을 제공한다.

구현

void	*ft_memset(void	*b, int c, size_t len)
{
	unsigned char	*ptr; // Description에서 `c`는 unsigned char로 변환되어 쓰이기에 unsigned char *로 선언
	unsigned char	value; // Description에서 `c`는 unsigned char로 변환되어 쓰이기에 unsigned char로 선언

	ptr = (unsigned char *) b;
	value = (unsigned char) c;
	while (0 < len) // len > 0으로 쓰는 것이 더 전통적인 방법이긴 하다.
	{
		*ptr = value;
		ptr++;
		len--;
	}
	return (b);
}
profile
작은 문제를 하나하나 해결하며, 누군가의 하루에 선물이 되는 코드를 작성해 갑니다.

0개의 댓글