Today
-
Yesterday
-
Total
-
  • 💡 [C언어] memset 함수 설명 및 자세한 예시
    | 프로그래밍 분야/C 2021. 5. 3. 17:37

    💡 memset 함수의 정의

    ✔︎ man memset

    NAME
         memset -- fill a byte string with a byte value

    LIBRARY
         Standard C Library (libc, -lc)

    SYNOPSIS
         #include <string.h>

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

    DESCRIPTION
         The memset() function writes len bytes of value c (converted to an unsigned char) to the string b.

    RETURN VALUES
         The memset() function returns its first argument.

     

    memset 함수는 string.h, memory.h 내장함수이다.

    둘 중 어느 것을 써도 기능상 동일하다.

     

    memset 함수는 지정해준 주소로부터 접근 가능한 값들을 1byte 단위로 다른 값으로 변경할 수 있다.

    그리고 그 주소를 다시 리턴한다.

     

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

    b는 변경할 값의 주소이다.

    c는 변경할 값이다.

    len은 변경할 값의 갯수이다.

    size_t 자료형이란?
     

    [C/C++] size_t 자료형의 정의

    size_t 아래는 C99의 원문이다. size_t can store the maximum size of a theoretically possible object of any type. 즉, 32비트 환경에서는 32비트, 64비트 환경에서는 64비트의 unsigned 변수로써 다음과 같..

    meoru-tech.tistory.com

    💡 테스트케이스

    <<TEST ~ ft_memset>>
    ---------- ft_memset(str, 'a', 4)
    Original : Hello World!
    Result : aaaao World!
    Compare : aaaao World!

    ---------- ft_memset(str1, 48, 3)
    Original : Hello World!
    Result : 000lo World!
    Compare : 000lo World!

    ---------- ft_memset(list, 1, sizeof(int))
    Original : {0, 1, 2, 3, 4, 5, 6, 7}
    Result : {16843009, 1, 2, 3, 4, 5, 6, 7}
    Compare : {16843009, 1, 2, 3, 4, 5, 6, 7}

    ---------- ft_memset(list1, 1, 2)
    Original : {0, 1, 2, 3, 4, 5, 6, 7}
    Result : {257, 1, 2, 3, 4, 5, 6, 7}
    Compare : {257, 1, 2, 3, 4, 5, 6, 7}

    ---------- ft_memset(list2, 42, sizeof(int) * 4)
    Original : {0, 1, 2, 3, 4, 5, 6, 7}
    Result : {707406378, 707406378, 707406378, 707406378, 4, 5, 6, 7}
    Compare : {707406378, 707406378, 707406378, 707406378, 4, 5, 6, 7}

    ---------- ft_memset(list3, 0, sizeof(int) * 8)
    Original : {0, 1, 2, 3, 4, 5, 6, 7}
    Result : {0, 0, 0, 0, 0, 0, 0, 0}
    Compare : {0, 0, 0, 0, 0, 0, 0, 0}

    ---------- ft_memset(list4, -1, sizeof(int) * 8)
    Original : {0, 1, 2, 3, 4, 5, 6, 7}
    Result : {-1, -1, -1, -1, -1, -1, -1, -1}
    Compare : {-1, -1, -1, -1, -1, -1, -1, -1}

    ---------- ft_memset(list5, -2, sizeof(int) * 8)
    Original : {0, 1, 2, 3, 4, 5, 6, 7}
    Result : {-16843010, -16843010, -16843010, -16843010, -16843010, -16843010, -16843010, -16843010}
    Compare : {-16843010, -16843010, -16843010, -16843010, -16843010, -16843010, -16843010, -16843010}

    ---------- ft_memset(list6, 42, 1)
    Original : {512, 1, 2, 3, 4, 5, 6, 7}
    Result : {554, 1, 2, 3, 4, 5, 6, 7}
    Compare : {554, 1, 2, 3, 4, 5, 6, 7}

     

    테스트케이스 실행코드
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    #include <stdio.h>;
    #include <string.h>;
    #include <stdlib.h>;
    #include "libft.h"

    void ft_putstr(char *dst, char *src)
    {
        while (*src)
            *(dst++= *(src++);
    }

    void int_list_out(int *list, int len, char flag)
    {
        int i;
        if (flag == 'R')
            printf("Result");
        else if (flag == 'C')
            printf("Compare");
        printf("        :    {");
        i = 0 - 1;
        while (++&amp;lt; len - 1)
            printf("%d, ", list[i]);
        printf("%d}\n", list[i]);
        if (flag == 'C')
            printf("\n");
    }

    void list_set(int *list)
    {
        int i;
        i = 0 - 1;
        while (++&amp;lt; 8)
            list[i] = i;
    }

    int main()
    {
        int        i;
        char    *str;
        str = (char*)malloc(13);

        ft_putstr(str, "Hello World!");
        printf("&amp;lt;&amp;lt;TEST ~ ft_memset&amp;gt;&amp;gt;\n");
        printf("---------- ft_memset(str, 'a', 4)\n");
        printf("Original    :    %s\n", str);
        ft_memset(str, 'a'4);
        printf("Result        :    %s\n", str);
        ft_putstr(str, "Hello World!");
        memset(str, 'a'4);
        printf("Compare        :    %s\n\n", str);

        char    str1[13= "Hello World!";
        printf("---------- ft_memset(str1, 48, 3)\n");
        printf("Original    :    %s\n", str1);
        ft_memset(str1, 483);
        printf("Result        :    %s\n", str1);
        ft_putstr(str1, "Hello World!");
        memset(str1, 483);
        printf("Compare        :    %s\n\n", str1);

        int        list[8= {01234567};
        printf("---------- ft_memset(list, 1, sizeof(int))\n");
        printf("Original    :    {0, 1, 2, 3, 4, 5, 6, 7}\n");
        ft_memset(list, 1sizeof(int));
        int_list_out(list, 8'R');
        list_set(list);
        memset(list, 1sizeof(int));
        int_list_out(list, 8'C');

        int        list1[8= {01234567};
        printf("---------- ft_memset(list1, 1, 2)\n");
        printf("Original    :    {0, 1, 2, 3, 4, 5, 6, 7}\n");
        ft_memset(list1, 12);
        int_list_out(list1, 8'R');
        list_set(list1);
        memset(list1, 12);
        int_list_out(list1, 8'C');

        int        list2[8= {01234567};
        printf("---------- ft_memset(list2, 42, sizeof(int) * 4)\n");
        printf("Original    :    {0, 1, 2, 3, 4, 5, 6, 7}\n");
        ft_memset(list2, 42sizeof(int* 4);
        int_list_out(list2, 8'R');
        list_set(list2);
        memset(list2, 42sizeof(int* 4);
        int_list_out(list2, 8'C');

        int        list3[8= {01234567};
        printf("---------- ft_memset(list3, 0, sizeof(int) * 8)\n");
        printf("Original    :    {0, 1, 2, 3, 4, 5, 6, 7}\n");
        ft_memset(list3, 0sizeof(int* 8);
        int_list_out(list3, 8'R');
        list_set(list3);
        memset(list3, 0sizeof(int* 8);
        int_list_out(list3, 8'C');
        int        list4[8= {01234567};
        printf("---------- ft_memset(list4, -1, sizeof(int) * 8)\n");
        printf("Original    :    {0, 1, 2, 3, 4, 5, 6, 7}\n");
        ft_memset(list4, -1sizeof(int* 8);
        int_list_out(list4, 8'R');
        list_set(list4);
        memset(list4, -1sizeof(int* 8);
        int_list_out(list4, 8'C');

        int        list5[8= {01234567};
        printf("---------- ft_memset(list5, -2, sizeof(int) * 8)\n");
        printf("Original    :    {0, 1, 2, 3, 4, 5, 6, 7}\n");
        ft_memset(list5, -2sizeof(int* 8);
        int_list_out(list5, 8'R');
        list_set(list5);
        memset(list5, -2sizeof(int* 8);
        int_list_out(list5, 8'C');

        int        list6[8= {5121234567};
        printf("---------- ft_memset(list6, 42, 1)\n");
        printf("Original    :    {512, 1, 2, 3, 4, 5, 6, 7}\n");
        ft_memset(list6, 421);
        int_list_out(list6, 8'R');
        list6[0= 512;
        memset(list6, 421);
        int_list_out(list6, 8'C');

        return (0);
    }
    cs

     

    ✔︎ 해설

    1byte단위로 자료가 수정되므로, 문자열을 수정할 때에는 'x' 혹은 아스키코드 값으로 활용하면 된다.

    숫자(int) 배열을 수정할 때에는 0(00000000), -1(11111111)값은 정상적으로 대입되나, 그 외의 값은 정상적으로 대입되지 않는다.

     

    int는 (일반적으로) 4바이트이므로 2진법으로 따졌을 때 다음과 같다.

    0 = 00000000 00000000 00000000 00000000

    -1 = 11111111 11111111 11111111 11111111

    1 = 00000000 00000000 00000000 00000001

    512 = 00000000 00000000 00000001 00000000

     

    memset() 은 1바이트 단위로 값을 수정하므로, 위 값들에 memset(num, 0, sizeof(int)) 를 적용하면 다음과 같다.

    0 ➜ 00000000 00000000 00000000 00000000 = 0

    -1  ➜ 00000000 00000000 00000000 00000000 = 0

    1  ➜ 00000000 00000000 00000000 00000000 = 0

    512 ➜ 00000000 00000000 00000000 00000000 = 0

     

    memset(num, -1, sizeof(int)) 를 적용하면 다음과 같이 모두 정상적으로 -1이 된다.

    0 ➜ 11111111 11111111 11111111 11111111 = -1

    -1 ➜ 11111111 11111111 11111111 11111111 = -1

    1 ➜ 11111111 11111111 11111111 11111111 = -1

    512 ➜ 11111111 11111111 11111111 11111111 = -1

     

    반면 memset(num, 1, 1) 을 순서대로 적용하면 다음과 같이 수정된다.

    0 ➜ 00000000 00000000 00000000 00000001 = 1

    -1 ➜ 11111111 11111111 11111111 00000001 = -256

    1 ➜ 00000000 00000000 00000000 00000001 = 1

    512 ➜ 00000000 00000000 00000001 00000001 = 513

     

    memset(num, 1, sizeof(int)) 를 적용하면 다음과 같이 수정된다.

    0 ➜ 00000001 00000001 00000001 00000001 = 16843009

    -1 ➜ 00000001 00000001 00000001 00000001 = 16843009

    1 ➜ 00000001 00000001 00000001 00000001 = 16843009

    512 ➜ 00000001 00000001 00000001 00000001 = 16843009

     

    다른 여러 상황들도 생각해볼 수 있을것이다.

    결국, 숫자 자료형을 정상적으로 수정할 수 있는 경우는 memset(num, 0, sizeof(int)) 혹은 -1 뿐이다.

     

    💡 예외 상황

    본 코드에서는 초기화와 동시에 선언되어 할당된 값을 참조하기 때문에 에러가 발생하지 않지만, 이런 방법 혹은 malloc() 을 통해 할당되지 않은 메모리에 memset 을 통해 접근 시 (당연히) 에러가 발생한다.

sangilyoon.dev@gmail.com