[C, C++] memset을 이용한 정수배열 초기화

서론

memset은 배열을 초기화할때 유용하게 사용할 수 있다. 반복문을 사용하는것보다 간편하고 시간복잡도에서 약간의 우위를 가진다.

본론

정수 배열을 0, -1로 초기화

#include <string.h>

int map[100][100];

int main(){
	memset(map, 0, sizeof(map));
}

C에서는 string.h, C++에서는 cstring을 불러오고 0으로 배열 초기화를 원하는 곳에서 아래와 같이 쓴다.

memset(원하는 배열, 0, 배열크기)

-1로 초기화를 원하면, 0대신 -1을 쓴다.

위 코드와 같이 여러차원의 배열도 초기화 할 수 있다. 그러나 memset은 바이트 단위로 초기화 하므로 엄밀하게 0, -1이외의 수는 초기화 할 수 없다.

정수 배열을 2139062143, -2122219135로 초기화

#include <cstring>

int map[100][100];

int main(){
	memset(map, 0x7f, sizeof(map));
	if(map[0][0] == 0x7f7f7f7f) cout<<"out";
}

알고리즘 문제풀이 할때 주로 사용하는데, 위와 같은 방법으로 배열을 2,139,062,143으로 초기화 할 수 있다. 32비트 컴퓨터 정수의 최대 크기가 2,147,438,647이므로 최대값에 가까운것을 볼 수 있다. 그러나 엄밀하게 최대값이 나오는건 아니라서 정밀한곳에 사용할 수는 없다.

memset은 바이트 단위로 메모리를 초기화하고, int는 4바이트인지라 0x7f라고 쓰면 0x7f7f7f7f가 된다. 따라서 정수 2,139,062,143은 0x7f7f7f7f다. 조건문등을 작성할때는 0x7f7f7f7f라고 써야한다.

0x7f 대신 -0x7f라고 초기화하면 -2122219135를 얻을 수 있다.

함수의 매개변수로 받아온 배열 초기화

함수의 매개변수로 배열을 받아오고 함수 내에서 memset을 초기화할 수 있다.

void func(int *a) {
	memset(a, 0, sizeof(a)*5);
}

int main() {
	int a[5] = { 1,2,3,4,5 };
	func(a);
	for (int i = 0; i < 5; i++) std::cout << a[i] << " ";
}

위 코드의 출력결과는 아래와 같다.

0 0 0 0 0

함수에서 배열을 받아올때는 참조호출이라서 함수 내부에서 main에 있는 배열을 초기화시켜줄 수 있다. 저기서 중요한것은 함수 내부의 memset의 size를 그냥 a가 아닌 배열의 크기만큼을 곱해줘야한다.

만약 곱해주지 않는다면 출력결과는 배열의 첫 수만 0으로 초기화가 된다.

0 1 2 3 4

(배열을 생성할때는 배열의 사이즈를 저장하고 있다가 함수의 매개변수로 넘겨줄때는 배열 주소값의 사이즈만 넘기는것같은데 혹시 이유를 정확하게 알고 계시면 이 글을 보는 다른분들을 위해 알려주시면 감사하겠습니다.)

Leave a Comment