memset
흔히 memset 을 사용하는 용도로는 함수명 그대로 memory에 저장된 값을 특정한 값으로 치환하기 위해서다.
예를 들면 다음과 같다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#include<stdio.h>
#include<string.h>
int main()
{
char str[30] = "hello, world";
printf("%s\n", str);
memset(str, 0, sizeof(str));
printf("%s\n", str);
return 0;
}
|
cs |
위의 코드는 "hello, world" 라는 문자열로 초기화 되어 있는 char 배열 str을 널값 0 로 초기화하는 것이다.
당연히 출력하면 아무것도 안 나온다.
함수 원형은 다음과 같다.
void* memset(void* ptr, int value, size_t num);
먼저 초기화 할 데이터의 주솟값을 첫 인자로, 수정할 값을 두번째, 마지막으로 길이(바이트 단위) 이다.
보통은 0으로 초기화를 한다. 예를 들면 int 형 배열을 0으로 초기화 할 때, 반복문을 사용해도 되지만 memset을 이용할 수도 있다.
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
|
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{
char str[30] = "hello, world";
int arr[20];
printf("%s\n", str);
memset(str, 0, sizeof(str));
printf("%s\n", str);
for(int i = 0; i < sizeof(arr) / sizeof(int); i++)
arr[i] = 1;
for(int i = 0; i < sizeof(arr) / sizeof(int); i++)
printf("%d ", arr[i]);
memset(arr, 0, 20 * sizeof(int));
for(int i = 0; i < sizeof(arr) / sizeof(int); i++)
printf("%d ", arr[i]);
return 0;
}
|
cs |
위의 코드에서 1로 초기화 한 arr[20] 은 memset을 통해 0으로 치환된다. 문제는 memset 을 통해 값을 치환할 경우 0 이나 -1은 제 값이 잘 들어가는데, 이 외의 다른 값들은 이상하게 들어간다. 출력하면 이렇게 나온다.
arr[20] 의 값을 byte 단위로 총 32byte 만큼 1로 초기화 했다. 상식 선에서는 1, 1, 1, ... 1 이렇게 출력될 것 같지만, 실제는 저 숫자, 84215045 이렇게 출력된다. 왜 그럴까?
디버깅에서 저장된 메모리를 확인하면 다음과 같다.
각 바이트는 1로 초기화 되었고, int는 4 바이트이므로 0x01010101 로 초기화되었다.
출력 화면은 다음과 같다. 16843009, 계산기로 확인결과 값은 마찬가지다.
아, memset은 바이트 단위로 초기화하기 때문에 int 형으로 출력하게 되면 4바이트를 읽어들여 10진수로 변환한다.
그래서 0x01010101 을 10진수로 변환해 16843009 란 값이 나오는구나...
그럼 왜?? -1은 잘 될까? 그 이유는 -1은 0xFFFFFFFF 의 10진수 정수이므로 문제없이 출력이 된 것이다.
memset의 활용은 아무래도 문자열의 문자를 변경할때가 아닌가 싶다. 1바이트 단위로 값을 변경하거나, 0으로 초기화 할때 반복문을 활용하는 것보단 memset으로 쉽게 초기화하는게 맞지 않나 싶다.