2차원 배열을 malloc로 생성해 보자.
2차원 배열은 1차원 배열보다 더 복잡하다.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
#define col_size (2) // 3x2 배열을 만들어 보자.
#define row_size (3)
/*
int arr[3][2] ={
{1,2},
{3,4},
{5,6}
}
*/
int** arr = NULL; // 2차원이므로 2중 포인터
arr = (int**)malloc((col_size) * sizeof(int*)); // 2*4= 8바이트의 메모리 생성
// 첫번재로 컬럼을 생성하자.
// 주의할점: 이렇게 하면 의도와 다르지만 동작한다.
// arr = (int**)malloc((col_size) * sizeof(int));
// ★ 칼럼에 int*가 들어가야 하는데, int*=4바이트, int=4바이트라서 사이즈가 맞다.
// 하지만 나중에 일차원 포인터를 연결할수는 없다.
// 두번째로 로우를 생성하자.
// for로 돌려도 되고
// 포인터 연산으로 해도 된다.
// 보기 편하라고 차례대로 나열했다.
if (arr == NULL) { return; }
arr[0] = (int*)malloc(row_size * sizeof(int)); // 3 * 4 = 12 바이트 메모리 생성
arr[1] = (int*)malloc(row_size * sizeof(int));
for (int i = 0; i < col_size; i++) {
for (int j = 0; j < row_size; j++) {
//arr[i][j]= 0; // 배열을 쓰면 계속 포인터가 NULL이 아니냐고 물어본다.
*(*(arr+i)+j) = 0; // 배열이 아니기 때문에 포인터 연산으로 해야만 한다.
// 메모리 생성후 이렇게 초기화 하는게 번거로울때 calloc 함수를 쓰면 편리하다.
}
}
printf("\\r\\n");
// 이제 사용자가 원하는 값을 넣으면 된다.
// 그런데 배열에 비해 상당히 불편하다.
*(*(arr + 0) + 0) = 11; // arr[0][0] = 11, 의미상 이렇다는 거지
*(*(arr + 0) + 1) = 12; // arr[0][1] = 12;
*(*(arr + 0) + 2) = 13; // arr[0][2] = 13;
*(*(arr + 0) + 0) = 21; // arr[1][0] = 21;
*(*(arr + 0) + 0) = 22; // arr[1][1] = 22;
*(*(arr + 0) + 0) = 23; // arr[1][2] = 23;
// 제대로 들어갔는지 출력해보자.
for (int i = 0; i < col_size; i++) {
for (int j = 0; j < row_size; j++) {
//printf("%d, ", arr[i][j]);
printf("%d, ", *(*(arr + i) + j));
}
}
// 해제도 꼭 해줘야 한다.
free(arr[0]); // ★★★★★ 꼭 써주자! 잊어서는 안된다.
free(arr[1]);
*(arr+0) = NULL; // 2차원 배열은 순서도 맞춰줘야 한다.
*(arr+1) = NULL; // 개별 1차원을 free 해주고, 최종 2차원 배열의 메모리를 해제해 줘야 한다.
free(arr); // 이 반대로 해줄경우 에러 혹은 댕글링 포인터가 된다.
arr = NULL;
return 0;
}