본문 바로가기
IT 톺아보기/이런저런 공부

memset 사용법

by 파초우 2023. 4. 20.
반응형

목차

memset()이란

C언어에서 메모리 할당에 주로 사용되는 것이 있는데, 그 중 하나가 memeset()이라는 함수이다. 이를 사용하면 메모리의 내용을 한꺼번에 특정 값으로 성정할 수 있어, 초기화 하는데 편리함이 있다.

memset()은 string.h에 정의되어 있는 function으로 memory block에 특정한 값을 채우고 크기를 지정해줄 수 있는 함수이다.

#include <string.h>
void *memset(void *ptr, int value, size_t num);

위처럼 사용할 수 있고

각, 인수들은 아래와 같이 정의 되어 있다.

`ptr`은 우리가 사용할 memory block의 주소를 가리킨다.
`value`는 설정할 값이다.
`num`은 우리가 사용할 메모리의 크기를 지정해준다.

memset() 사용 예시

memset는 아래와 값이 사용을 하는데,

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

int main() {
    int arr[5];
    memset(arr, 0, sizeof(arr)); // arr에 0을 할당
    for (int i = 0; i < 5; i++) {
        printf("%d\t", arr[i]); //output is 0    0    0    0    0
    }

    return 0;
}

출력값이 0 0 0 0 0이 나오는 것을 볼 수 있다.

만약, memset()의 value에 0이 아닌 값을 넣게 된다면,

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

int main() {
    int arr[5];
    memset(arr, 1, sizeof(arr)); // arr에 임의의 정수를 할당
    for (int i = 0; i < 5; i++) {
        printf("%d\t", arr[i]); //output is 16843009    16843009    16843009    16843009    16843009
    }

    return 0;
}

출력값이 16843009 16843009 16843009 16843009 16843009이 나오는 것을 볼 수 있다.

임의의 난수이기 때문에 매번 실행할 때마다 값이 다르게 출력될 것이다.

value 값 할당 시 주의점

value값에 있어서 주의할 점이 있다. value에 있어 초기화 값을 집어 넣는데, 0이 아닌 다른 값을 넣게 된다면 임의의 난수로 초기화될 가능성이 크다. 그 이유는 memset() 함수가 memory block의 byte를 0으로 채우는 것이 아닌 전달받은 value 인자로 설정하기 때문

만약 value 인자가 char 혹은 unsigned char type이 아니라, 다른 type으로 전달되면 해당 type의 값을 memory block에 채우기 위해 type 크기만큼 byte가 value 의 memory에서 사용됨. 그리고 만약 해당 type의 memory 값이 0이 아니면, memory block이 해당 값으로 채워지게 된다.

하지만, value 인자가 char 혹은 unsigned char type일 경우에는 0이 아닌 값이 전달 됐을 때, 해당 값이 부호 없는 8-bits정수로 변환되어 memory block에 채워지게 된다. 이 때, 값이 부호 없는 8-bits 정수의 범위를 초과하면, 값이 8-bits로 잘릴 수 있다. 따라서, 이 경우 임의의 난수가 채워질 가능성이 있다.

그러므로, memset() 함수에서 value 인자에 0이 아닌 값이 전달될 때는 이러한 위험성에 주의해야한다. 만약 0이 아닌 값을 memory block에 채우고 싶다면, memset() 함수대신에 반복문을 사용하여 수동으로 값을 채워주는 것이 좋다.

memeset() 사용 시 주의점

  1. 해당 함수는 오직 byte 단위로 memory를 초기화하기 때문에, 다른 자료형의 배열을 초기화할 때에는 주의가 필요하다. 만약 다른 자료형의 배열을 초기화 하려고 한다면, **sizeof() 연산자를 이용하여 배열 전체의 크기를 계산해야함**.
  2. 해당 함수는 포인터를 반환하기 때문에, 포인터 자료형의 변수에 대입하려면 캐스팅(casting)이 필요. 예를 들어, int **ptr = (int*) memset(arr, 0, sizrof(arr))); 처럼 사용이 가능*
  3. 해당 함수는 0 혹은 -1(혹은 0xff)로 초기화할 때 가장 효율적이다. 그러나 다른 값을 설정하기 위해서는 memset() 함수 대신 다른 방법을 고려해야 함
  4. 해당 함수는 memory block을 초기화하기 때문에, memory를 동적으로 할당한 경우에만 사용이 가능. 정적으로 할당된 memory나 stack memory는 초기화하기 위해서는 다른 방법을 이용해야 함
  5. 해당 함수는 문자열을 초기화하는 용도로 사용되는 경우가 많지만, 문자열을 초기화하기 위해서는 strcpy() 혹은 strncpy() 함수 등을 사용하는 것이 더 안전. why? 문자열을 초기화할 때 NULL을 반드시 포함해야하기 때문

memset_s() 함수

memset_s() 함수는 memset() 함수와 유사하지만, memory 영역을 초기화할 때 보안상의 이유로 데이터가 노출되는 것을 방지하기 위해 사용되는 기능입니다.

memset_s() 함수는 초기화할 memory 영역의 주소, 초기화할 값, 초기화할 데이터의 크기를 인자로 받읍니다.

반응형

'IT 톺아보기 > 이런저런 공부' 카테고리의 다른 글

LIN이란?  (0) 2023.05.08
memmove 사용법  (0) 2023.04.21
CAN Message  (0) 2023.04.19
memcpy 사용법  (0) 2023.04.18
CAN 통신  (1) 2023.04.17