대표적으로 배열과 같은 특정한 범위에 있는 연속적인 메모리에 값들을 지정할 때
memset 함수를 사용한다면 for문 보다 더 빠른 속도를 낼 수 있는 경우도 있다.
우선 함수의 원형은 void * memset ( void * ptr, int value, size_t num ); 이다.
이때 ptr은 채우고자 하는 메모리의 시작 주소이고, value는 값, num은 메모리의 크기이다.
다만 주의해야 할 점은 value가 int형이지만 내부적으로는 unsigned char(1byte)로 변환되어 저장된다.
#include <iostream>
#include <memory.h>
using namespace std;
int main()
{
int arr[10];
int brr[10];
memset(arr, 0, sizeof(arr));
memset(brr, -1, sizeof(brr));
for (int i = 0; i < 10; i++)
cout << arr[i] << ' ' << brr[i] << endl;
}
따라서 위의 예제 코드를 살펴보면 arr[10]과 brr[10]에 각각 0과 1로 초기화는 성공한 것을 확인할 수 있다.
내부적으로 살펴보면 정수 '0'과 '-1'은
각각 '00000000000000000000000000000000', '11111111111111111111111111111111'로 저장된다.
#include <iostream>
#include <memory.h>
using namespace std;
int main()
{
int arr[10];
memset(arr, 1, sizeof(arr));
for (int i = 0; i < 10; i++)
cout << arr[i]<<endl;
}
하지만 위와 같이 1로 초기화를 하려는 시도는 엉뚱한 값들이 들어간다.
이는 '1'이라는 정수가 내부에서는 '00000001000000010000000100000001'로 변환되기 때문이다.
따라서 1byte의 변수(char, unsigned char 등)를 제외하고는 0과 -1로만 초기화할 수 있다.
두 번째, 동적할당된 메모리를 초기화 할 때 조심해야 한다.
#include <iostream>
#include <memory.h>
using namespace std;
int main()
{
int N;
cin >> N;
int* arr = new int[N];
memset(arr, 0, sizeof(arr));
for (int i = 0; i < N; i++)
cout << arr[i] << endl;
}
엥? arr[0]은 0으로 초기화가 잘됐지만 arr[1]부터는 이상한 값들이 들어갔다.
위 코드에서 문제는 memset(arr, 0, sizeof(arr)); 이다.
왜냐하면 여기서 sizeof(arr)은 포인터의 크기 4byte이다. 따라서 arr이 가르키는 주소에서 시작해서
4byte만큼만 0으로 초기화하는 의미가 된다. 그래서 int형 배열의 하나의 원소(4바이트)만 초기화 된다.
#include <iostream>
#include <memory.h>
using namespace std;
int main()
{
int N;
cin >> N;
int* arr = new int[N];
memset(arr, 0, sizeof(int) * N);
for (int i = 0; i < N; i++)
cout << arr[i] << endl;
}
memset(arr, 0, sizeof(int) * N); 로 바꾸니까 올바른 결과값이 나온다!
셋 째.
new, malloc등을 이용하여 동적으로 배열을 생성하는 변수가 있는 구조체나 클래스는 memset으로 초기화를 할 수 없다.
#include <iostream>
#include <memory.h>
using namespace std;
struct A
{
int i;
char* c;
};
void main()
{
A a;
a.c = new char[100];
memset(&a, 0, sizeof(A));
if (a.c != NULL)
{
delete[] a.c;
a.c = NULL;
}
}
위 예제코드에서 sizeof(A)는 8바이트( int i(4byte) + char*c(4byte) )가 된다.
따라서 memset(&a, 0, sizeof(A)); 는 a의 변수 i와 c의 값을 모두 0으로 설정한다.
이때, a.c에 동적으로 할당된 배열들은 초기화가 되지 못하고 메모리 누수가 발생한다.
a.i = 0;
memset(a.c, 0, sizeof(char)*100);
그러므로 이 경우처럼 동적으로 할당될 때는 위와 같이 따로 초기화 해야한다.
참고: https://beautyrain.tistory.com/7
'씨플플' 카테고리의 다른 글
[C++] map, multimap container 정리 (0) | 2020.03.29 |
---|---|
[C++] pair 클래스에 대해서 (+ tuple) (0) | 2020.03.28 |
[C++] vector container 정리 (0) | 2020.03.05 |
[C++] std::cin.ignore(), std::cin.clear(), std::cin.fail() 함수 (0) | 2020.02.11 |