728x90

C에서 한번씩 고민하는게 배열을 도대체 어떻게 초기화 해야 하느냐이다.

왜냐하면 배열을 초기화 하는 함수가 없기 때문이다.

그래서 검색해서 보면 memset이라는 함수가 존재한다.


"배열을 초기화 하고 싶으면 memset"함수를 써보세요~!"

이 함수는 memory.h에 정의 되어있다.

그리고 memory.h는 string.h에 포함되어 있다.


이름부터 뭔가 배열과 관계가 없어보이는 이 함수의 역활은 무엇일까?

자세히 알고싶으면 여기를 확인하라.

여기서 확인해보면 함수의 형태는 아래와 같다.


void *memset( void *dest, int ch, size_t count );


여기서 말하는 dest는 덮어쓸 배열이며 ch는 덮어쓸 값이다. 그리고 count는 덮어 쓸 갯수이다.

그런데 마지막 이놈이 문제다. 갯수라는 개념은 배열의 갯수가 아니라 메모리 바이트 갯수를 의미한다.

가령 아래의 예를 들어보자.


#define MAXSIZE 10
int arr[MAXSIZE];

배열의 크기는 10이지만 바이트 크기는 int형의 크기 * 10이다.

여기서 int형의 크기는 필자의 경우는 4바이트이다. 즉 위는 40바이트라는 것이다.


memset(arr, -1, MAXSIZE);

만약 배열의 값을 모두 -1로 덮고 싶다면 위와 같이 써야할까?

결과를 보면 전혀 아니라는 것을 알 수 있다. 그 힌트는 위에서 언급했다시피 바이트 단위로 덮어쓰기 때문이다.

일단 먼저 결과를 보자.


-1 -1 65535 0 0 0 0 0 0 0 

보다시피 출력을 해도 제대로 되지 않는다.


그 이유는 -1이 1바이트씩 덮어써서 MAXSIZE만큼 덮어쓰기 때문이다.

앞의 두개를 즉 -1을 10바이트를 덮어쓰기 때문에 int(여기서는 4바이트)를 두개 덮고 마지막 하나는 절반만 덮어 쓰는 것이다.

그래서 제대로 쓰려면 아래와 같이 사용해야한다.


memset(arr, -1, MAXSIZE * sizeof(int));

위와 같이 사용하면 이제 int형크기만큼 더 덮어쓰게된다.

출력을 보면된다.


-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 

만약 여러분이 덮어쓰고자 하는게 long long 형이면 sizeof에 long long을 넣어주면 된다.


그럼 여기서 ch는 정말 받는 인자는 int형이지만 실상은 char형만 쓴다는 것을 확인할 수 있다.

즉 받기는 4바이트를 받지만 쓸때는 1바이트만 꺼집어 내서 쓴다는 것이다.

이 함수의 특징 때문에 또다른 문제를 야기하게 된다.


#define INF 0x7FFFFFFF
memset(arr, INF, MAXSIZE * sizeof(int));

만약 이런 상황에서 0x7FFFFFFF(F가 7개이다.)는 int가 표현가능한 가장 큰 수이다. 21억이 넘는 수인데 이 값은 4바이트이다.

이런 값은 memset특성상 덮어 쓸수 없다.

이 경우에 배열을 초기화 해주려면 반드시 for문을 사용해야한다는 문제점이 있다.


+ Recent posts