동적할당
정적 메모리 할당과 달리 상황에 따라 필요한 크기만큼의 메모리를 할당하는 것
⇒ heap 영역에 메모리 할당
포인터와 C언어 제공 라이브러리 함수를 활용한다
메모리할당 함수
•
<stdlib.h>에 정의되어 있는 malloc(), calloc(), realloc()
•
malloc() : 사용자가 원하는 크기만큼 메모리 할당
•
calloc() : 사용자가 원하는 크기만큼 메모리를 할당하고 0으로 초기화. 주로 배열/구조체 타입의 동적메모리 할당시 사용한다
•
realloc() : 기존에 저장되어 있던 데이터는 유지하고 메모리의 크기만 변경
메모리 해제 함수
•
free()
•
동적할당이라는 것 자체가 프로그래머가 상황에 맞춰 필요한 만큼의 메모리를 사용하겠다고 컴퓨터에게 요청해 빌리는 것이기 때문에 사용이 끝나면 반드시 반납해줘야 한다. == 메모리해제
int *arr;
arr = (int *)malloc(sizeof(int)*5);
if (arr==NULL) exit(1);
free(arr); // free()의 파라미터에 메모리를 반환할 변수 넣어줌
C
복사
•
메모리 해제 작업 해주지 않으면 해당 메모리 영역은 컴퓨터가 필요할 때 사용할 수 없게 될 수도 있음 == 메모리 누수
•
메모리 누수 → 컴퓨터가 사용 가능한 메모리 감소 → 성능 저하
#include <stdio.h>
#include <stdlib.h>
int main() {
int *pi = NULL; // NULL pointer : 포인터 변수를 초기화하기 위한 용도
pi = (int *)malloc(sizeof(int)*1); // pi에 4byte만큼의 메모리 할당
if (pi==NULL) exit(1);
printf("%d", *pi); // 쓰레기값이 출력된다
free(pi); // 프로그램 종료 전 반드시 메모리 해제
return 0;
}
C
복사
#include <stdio.h>
#include <stdlib.h>
int main() {
int *pi = NULL; // NULL pointer : 포인터 변수를 초기화하기 위한 용도
pi = (int *)calloc(sizeof(int)*1); // pi에 4byte만큼의 메모리 할당
if (pi==NULL) exit(1);
printf("%d", *pi); // 0이 출력된다 -> calloc함수는 메모리 할당과 동시에 0으로 초기화
free(pi); // 프로그램 종료 전 반드시 메모리 해제
return 0;
}
C
복사
int *pi = NULL; // NULL pointer : 포인터 변수를 초기화하기 위한 용도
pi = (int *)malloc(sizeof(int)*1); // pi에 4byte만큼의 메모리 할당
: 앞에 (int *)는 리턴형이다. int형 포인터로 리턴한다는 의미이다.
함수별 1차원 배열 동적 할당
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 5;
int* arr1;
arr1 = (int *)malloc(sizeof(int)*n); // n개의 int형 배열 할당
int n = 7;
double* arr2;
arr2 = (double *)calloc(n, sizeof(double)); // n개의 int형 배열 할당하고 0으로 초기화
arr2 = realloc(arr2, sizeof(double)*4); // 데이터는 유지하고 4개의 double형 배열 할당
return 0;
}
C
복사
[calloc를 이용한 1차원 배열 동적할당]
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 4;
int* pi = NULL; // NULL pointer
pi = (int*)calloc(n, sizeof(int)); // n개의 int형 배열을 할당하고 0으로 초기화
if (pi == NULL) exit(1);
for (int i = 0; i < n; i++)
printf("%d\n", pi[i]);
free(pi);
return 0;
}
C
복사
[malloc를 이용한 1차원 배열 동적할당]
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 4;
int* pi = NULL; // NULL pointer
pi = (int*)malloc(n, sizeof(int));
if (pi == NULL) exit(1);
pi[0] = 1;
pi[1] = 2;
pi[2] = 3;
for (int i = 0; i < n; i++)
printf("%d\n", pi[i]); // 1, 2, 3이 순서대로 출력된 후 쓰레기값 출력되면서 오류남
free(pi);
return 0;
}
C
복사
[realloc를 이용한 1차원 배열 동적할당]
realloc은 할당 실패시 기존의 데이터도 잃을 수 있기 떄문에 주의가 필요합니다!
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 4;
int* pi = NULL; // NULL pointer
pi = (int*)calloc(n, sizeof(int));
if (pi == NULL) exit(1);
for (int i=0; i < n; i++)
pi[i] = i;
int m = 6;
int* ptemp;
ptemp = (int*)realloc(pi, sizeof(int) * m); // 파라미터로 포인터가 들어감
if (ptemp == NULL) exit(1);
for (int i = 0; i < m; i++)
printf("%d\n", ptemp[i]);
free(pi);
free(ptemp);
return 0;
}
C
복사
기존 pi에서 복사된 1, 2, 3
realloc 이후 추가된 배열 2개 출력
11p. Q. 왜 realloc이 후 추가된 값은 같은 값을 갖나요? 쓰레기값이라고 하셨는데 두 값이 같을 뿐 아니라 교수님 결과와 내 결과도 같음
2차원 배열의 동적 메모리 할당
이중포인터와 라이브러리 함수 사용
// ex. 5 x 10 행렬(int형 2차원 배열)
int **p;
p = (int**)malloc(sizeof(int*)*5); // 행을 만들어냄
if (p == NULL) exit(1);
for (int i=0;i < 5; i++){
p[i] = (int*)malloc(sizeof(int)*10); // 열을 만들어냄
if (p[i] == NULL) exit(1);
}
C
복사
2차원 배열의 동적할당 == 동적할당 2번
첫번째는 행, 두번째는 열을 생성
[malloc를 이용한 2차원 배열 동적할당]
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 3, m = 5; // n x m의 2차원배열 생성할 것
double** p;
p = (double**)malloc(n, sizeof(double));
if (p == NULL) exit(1);
for (int i = 0; i < n; i++) {
p[i] = (double*)malloc(sizeof(double) * m); // 1개의 행당 m개의 열 생성
if (p[i] == NULL) exit(1);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
printf("%d ", p[i][j]);
}
printf("\n");
}
// 할당 해제 하는 부분 -> n + 1번 해제해주어야한다.
for (int i = 0; i < n; i++) {
free(p[i]);
}
free(p);
return 0;
}
C
복사
[해제가 수월하도록 하는 다른 방법 ( 강의 외 내용) ]
int height=8,width=6;
int **arr;
arr = (int **) malloc ( sizeof(int *) * height);
arr[0] = (int *) malloc ( sizeof(int) * width*height );
for( int i=1; i<height; i++){
arr[i] = arr[ i-1 ] + width;
}
free(arr[0]);
free(arr);
C
복사
그림으로 나타내면 다음과 같음
[calloc를 이용한 2차원 배열 동적할당]
#include <stdio.h>
#include <stdlib.h>
int main() {
int n = 3, m = 5; // n x m의 2차원배열 생성할 것
double** p;
p = (double**)calloc(n, sizeof(double));
if (p == NULL) exit(1);
for (int i = 0; i < n; i++) {
p[i] = (double*)calloc(m, sizeof(double)); // 1개의 행당 m개의 열 생성
if (p[i] == NULL) exit(1);
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
printf("%d ", p[i][j]);
}
printf("\n");
}
for (int i = 0; i < n; i++) {
free(p[i]);
}j
free(p);
return 0;
}
C
복사
0으로 초기화된 모습