C - 동적할당

원종서·2023년 2월 15일
0

C

목록 보기
1/3

2023/2/16

동적할당의 필요성.

동적할당을 이용하지 않고 배열을 생성하면 컴파일 단계 때 명확한 배열의 크기를 지정해주어야한다.
안정적으로 배열을 생성하기 위해서는 필요한 메모리의 양보다 넉넉하게 생성해 주어야 하는데, 이러한 넉넉함은 자원의 낭비를 불러 일으킬 수 있다.

동적할당이란

위의 문제를 해결하기 위해 가변적으로 메모리를 할당할 수 있는 것이 동적할당이다.

#include  <stdio.h>
#include <stdlib.h>

int main(int args,  char **argv) {
	int sizeOfArray;
    int *arr;
    
    scanf("%d", &sizeOfArray);
    
    // malloc (memory allocation) 을 사용해 동적할당.
    // stdlib 에 정의되어 있음으로 stdlib해더 파일 추가.
    // malloc의 반환값은 할당한 메모리의 시작 주소
    arr = (int*)malloc(sizeof(int) * sizeOfArray);
    
    // use arr ...
    
    // 할당한 메모리를 반환
    // 적절하게 free를 해주지 않으면, 메모리 누수로 프로그램이 다운될 수 있다.
    free(arr);
}

malloc의 할당 위치.

메모리의 Heap 영역에 생성.

2차원 배열의 동적할당.

1. 포인터 배열을 사용해 2차원 배열처럼 동작하는 배열 생성

#include <stuio.h>
#include <stdlib.h>

int main(int argc, char** argv) {
	int i, x, y;
    int **arr;
    
    scanf("%d %d", &x,&y);
    
    arr = (int**)malloc(sizeof(int*) * x);
    
    for(int i = 0 ; i< x ; i++){
    	arr[i] = (int*)malloc(sizeof(int) * y);
    }
    
    // use arr ...
    
    for(int i = 0 ; i< x ; i++) {
    	free(arr[i]);
    }
    
    free(arr);
}

단 동적으로 생성된 포인터 배열은 2차원 배열이라고 단정 지을 수 없다.
포인터 배열의 2차원 배열의 동적할당은 메모리가 연속적으로 있다는 보장이 없기 때문이다.

때문에

int func(int **arr) {...}

의 함수의 매개변수로 사용할 수 있다.
2차원 배열처럼 행동하지만 사실은 int* 타입의 1차원 배열이다. (2차원 배열을 매개변수로 사용될 경우, 열의 정보를 알려주는 매개변수도 함께 전달되어야 했다)

진짜 2차원 배열 동적할당.

메모리가 나란히 위치된 2차원 배열 동적할당.

int arr[height][width]; 

의 2차원 배열을 동적할당 하고 싶을 때, 할당되어야 하는 메모리의 크기는

height * width * sizeof(int)
int (*arr)[width] = (int(*)[width])malloc(height * width * sizeof(int));

2차원 배열 포인터의 경우, 포인터 연산을 수행하기 위해서는 반드시 포인터 타입 안에 행 길이가 들어가야한다.
위의 예시에서 컴파일러는 행의 크기가 width의 2차원 배열임을 알 수 있다.


#include <stdio.h>
#include <stdlib.h>

// 2차원 배열의 열을 지정해주어야 하기 때문에, 매개변수의 순서가 아래와 같게 하는 것이 중요하다.
void add_one(int width , int (*arr)[width], int height) {
	for(int i = 0 ; i< height ; i++)
    	for(int j = 0 ; j < width ; j++)
        	arr[i][j]++
}



int main(){
	int width, int height;
    
    scanf("%d %d", &width, &height);
    
    int (*arr)[width] = (int(*)[witdh])malloc(height * width * sizeof(int));
    
    for(int i = 0 ; i< height ; i++){
    	for(int j =0 ; j< width ; j++){
        	scanf("%d" , &arr[i][j]);
        }
    }
    
    print_array(width ,arr , height);
    
    add_one(width, arr, height);
    
    free(arr);
}
    
}

결론.

전자보다는 후자의 방법이 좋으다.

0개의 댓글