티스토리 뷰
PS를 하다보면 배열을 초기화할 일이 아주 많다.
많이 하다보니 이젠 기계적으로 '아 초기화, std::fill()'처럼 별 생각 없이 함수를 사용해 초기화할 때가 많다.
아직 글을 많이 올리진 않았지만, 내 코드를 보면 알 수 있듯 난 배열을 초기화할 때 fill()을 자주 쓴다.
그리고 오늘 #11728: 배열 합치기를 풀다가
int n, m, num;
cin >> n >> m;
int size = max(n, m);
int* table[2];
for (int i = 0; i < 2; i++)
table[i] = new int[size];
fill(&table[0][0], &table[1][size], 0);
이런 코드를 썼는데 자꾸 에러가 났다. 그리고 고수님의 도움을 받아 그 이유를 알 수 있었다.
결론부터 말하자면 for로 2차원 배열을 할당했을 때, 그 2차원 배열이 연속적이지 않아서 fill()을 사용했을 때 에러가 생기는 것이었다. 2차원 배열을 동적으로 할당했을 때 그 배열이 연속적이지 않다는 것은 단순히 동적 할당된 배열들 첫번째 주소를 보면 알 수 있다.
int* arr[2];
for (int size = 1; size <= 20; size++) {
for (int i = 0; i < 2; i++)
arr[i] = new int[size];
cout << arr[0] << ' ' << arr[1] << " : " << arr[1] - arr[0] << '\n';
for (int i = 0; i < 2; i++)
delete(arr[i]);
}
심지어 음수가 나오기도 한다.
반면,
int arr1[2][1] = { 0 }, arr2[2][2] = { 0 }, arr3[2][3] = { 0 };
cout << arr1[0] << ' ' << arr1[1] << " : " << arr1[1] - arr1[0] << '\n';
cout << arr2[0] << ' ' << arr2[1] << " : " << arr2[1] - arr2[0] << '\n';
cout << arr3[0] << ' ' << arr3[1] << " : " << arr3[1] - arr3[0] << '\n';
cf) int arr[size] = {0} < 이런 식으로 선언하게 되면 모든 원소가 0으로 초기화된다.
(https://by-man.tistory.com/570 참고)
이차원 배열을 선언하고 그 주소를 보면
이렇게 연속적임을 알 수 있다. 내가 알기로 정적 할당된 2차원 배열은 연산과 형태가 1차원 배열의 그것과 같다.
이 주소 값들은 10진수로 각각
8059408 8059412
8059384 8059392
8059352 8059364
이고 그 차이는 각각 4, 8, 12로 배열의 크기와 딱 맞다는 것을 확인할 수 있다.
End
2차원 배열의 행을 개별적으로 동적할당 하면 그 2차원 배열의 행은 연속적이지 않다. 따라서 각각들 다른 배열로 생각하고 접근해야 한다.
항상 에러가 나고서야 깨닫는다. 쓰기 전에 생각하는 습관을 들이자.
도움 주신 고수님 감사합니다.