[C]memset


memset함수는 크기만큼 문자를 채우는 함수입니다.


1️⃣ 함수원형

< memset >

void *memset(void *ptr, int value, size_t size)

2️⃣ 헤더파일, 반환값

  • 반환값:

    조건반환값(void *)
    성공시복사완료된배열의 주소
    ptr이 NULL일때segmentation fault
    size > ptr크기윈도우: 경고없이 컴파일됨
    리눅스: 경고출력, 컴파일에러
    size = ptr크기컴파일됨(위험한상태)
  • 헤더파일: <string.h>


3️⃣ 함수구현

< memset >

void *memset(void *ptr, int value, size_t size)
{
	unsigned char	*pb;

    pb = ptr;
    while (size-- > 0)
    	*pb++ = value;
    return (ptr);

}


4️⃣ 특징 & 주의사항

  1. 자료형이 size_t인 size의 값이 음수가 되면 버퍼오버플로우(size_t는 unsigned형으로 선언되어 있기 때문)가 일어납니다. 컴파일러에 따라서 경고메시지를 출력해주고 컴파일이 되지 않습니다. 하지만 컴파일이 되는 경우가 있는데 소유하고 있지않는 메모리에 value값이 채워지므로 위험해질 수 있습니다.
  2. 메모리를 잘 다룰 수 있지 않는이상 1byte크기의 자료형만 사용하는 것이 좋습니다.(아래 자세한 내용)
  3. 0으로 초기화하는데 좋은 함수이며 2차원배열도 0으로 초기화 시켜줄 수 있습니다.(아래 자세한 내용)
  4. NULL문자(‘\0’)를 문장끝에 붙여주지 않기 때문에 크기를 잘 고려해서 사용해야 됩니다.
    ex> char word[5];를 다룬다면 3번째 인자의 값이 4가 되도록하여 끝의 ‘\0’를 그대로 두는 것이 안전 합니다.

5️⃣ 코드예시(특이케이스)


1. < 1byte가아닌 자룔형으로 memset함수 사용할 경우(특징2) >

#include <stdio.h>
#include <string.h>

int main(void)
{
	int word[6] = {1,2,3,4,5};
	int *temp;

	temp = k_memset(word, 3, 5 * sizeof(int));

	for (int i = 0; i < 5; i++)
		printf("%d ", temp[i]);
	printf("\n");
}
/* ---결과--- */
50529027 50529027 50529027 50529027 50529027
  • 기대값: 3 3 3 3 3
  • 출력값: 50529027 50529027 50529027 50529027 50529027
  • 원인: 4byte크기의 int자료형을 사용
  • 이유: memset함수는 내부적으로 (unsigned char[1byte])단위로 복사하게 됩니다. 위 코드의 경우 int형 자료형의 메모리가 1byte단위로 3이 복사되어 ‘03 03 03 03’가 되고 10진수로 50529027(= 0x03030303)이 됩니다.

  • 결론: 1byte단위로 값을 채우는 형식이기 때문에 1byte의 크기가아닌 자료형을 사용하면 예상치 못한 결과가 생길 수 있습니다. 하지만 단순히 0으로 초기화하는 것이 목적이라면 어떤한 자료형도 상관 없을 것 같습니다.

2. < 0으로 초기화할 경우(특징3) >

int main(void)
{
    char sample1[20];
	char sample2[6][10];
    int  sample3[20];

	char *result1;
    int  *result2;

    result1 = memset(sample1, 0, 20);
    printf("일차원배열: %s\n", result1);

	result2 = memset(sample2, 0, 6 * 10);
	printf("이차원배열: %s\n", result2[0]);

    result2 = memset(sample2, 0, 20 * sizeof(int));
    printf("int자료형: ");
    for(int i = 0; i < 19; i++)
        printf("%d ", result2[i]);
    printf("\n");
}
/*---출력---*/
일차원배열:
이차원배열: (null)
int자료형: 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
  • 이차원배열 또한 NULL포인터(void*(0))로 초기화가 잘 되었습니다.




© 2021.02. by kirim

Powered by kkrim