사자자리
[C언어] 7주차 동적 메모리 할당 본문
동적 메모리가 필요한 경우
- 배열의 크기를 미리 알 수 없을 때
//배열의 크기는 상수로 지정할 수 없다. 컴파일 에러.
int arr[size];
//배열의 최대 크기를 가정해서 할당하면, 메모리 낭비가 발생한다.
int arr[1000];
- 동적 메모리를 사용하면, 원하는 만큼 메모리를 할당할 수 있으므로 메모리 낭비를 최소화할 수 있다.
- 동적 메모리를 사용하면, 메모리의 할당과 해제 시간을 마음대로 선택할 수 있다.
동적 메모리의 할당과 해제
stdlib.h
- 메모리 관련 함수를 사용하기 위해 필요한 헤더
malloc 함수
- Memory ALLOCation
- 함수의 인자로 할당할 메모리의 바이트 크기를 입력한다.
free 함수
- 포인터가 가리키는 동적 메모리를 해제한다.
#include <stdio.h>
#include <stdlib.h>
int main(){
int size, sum = 0;
int *arr = NULL; //동적 메모리의 주소를 저장할 포인터
printf("몇 개의 정수를 입력하겠습니까?: ");
scanf("%d", &size);
arr = malloc(sizeof(int)*size); //동적 메모리의 할당
if (arr == NULL){
printf("동적 메모리 할당 실패\n");
return -1;
}
printf("%d개의 정수를 입력하세요: ", size);
for (int i = 0; i < size; i++){
scanf("%d", &arr[i]); //동적 메모리의 사용
sum += arr[i]; //동적 메모리의 주소를 저장하는 포인터 변수는 배열의 원소를 가리키는 포인터처럼 사용한다.
}
printf("합계: %d", sum);
free(arr); //동적 메모리의 해제
arr = NULL; //동적 메모리를 가리키던 포인터 변수에 NULL을 대입하는 것이 안전하다.
return 0;
}
<실행 결과>
몇 개의 정수를 입력하겠습니까?: 5
5개의 정수를 입력하세요: 1 3 5 7 9
합계: 25
동적 메모리와 구조체 포인터 배열
- 프로그램 실행 중에 구조체를 동적 메모리에 할당하고 그 주소만 포인터 배열에 저장해서 사용할 수 있다.
#include <stdio.h>
#include <stdlib.h>
typedef struct rectangle{
int width, height, area;
} RECT;
int main(){
int count = 0;
RECT *arr[100] = {NULL}; //구조체 포인터 배열의 선언
while(1){
char choice;
printf("직사각형을 생성하겠습니까? (Y/N) ");
scanf("%c", &choice);
getchar();
if (toupper(choice) == 'N') break;
arr[count] = malloc(sizeof(RECT)); //구조체에 대한 동적 메모리 할당
arr[count] -> width = rand() % 400 + 1;
arr[count] -> height = rand() % 400 + 1;
arr[count] -> area = (arr[count] -> width) * (arr[count] -> height);
count++;
}
printf("\n%d개의 직사각형이 만들어졌습니다.\n", count);
for (int i = 0; i < count; i++){
printf("%d번째 직사각형의 (가로, 세로, 넓이): (%3d, %3d, %5d)\n", i+1, arr[i] -> width, arr[i] -> height, arr[i] -> area);
}
for (int i = 0; i < count; i++){
free(arr[i]);
arr[i] = NULL;
}
return 0;
}
<실행 결과>
직사각형을 생성하겠습니까? (Y/N) Y
직사각형을 생성하겠습니까? (Y/N) Y
직사각형을 생성하겠습니까? (Y/N) N
2개의 직사각형이 만들어졌습니다.
1번째 직사각형의 (가로, 세로, 넓이): ( 42, 68, 2856)
2번째 직사각형의 (가로, 세로, 넓이): (335, 101, 33835)
동적 메모리 관련 함수
void *malloc(size_t size); | 동적 메모리를 할당한다 |
void *calloc(size_t num, size_t size); | 동적 메모리 배열(num*size)을 할당하고 0으로 초기화한다 |
void *realloc(void *memblock, size_t size); | 동적 메모리의 크기를 변경해서 재할당한다 |
void free(void *memblock); | 동적 메모리를 해제한다 |
정적 메모리 VS 동적 메모리
정적 메모리 | 동적 메모리 | |
메모리 할당 | 컴파일 시간에 이루어짐 | 실행 시간에 이루어짐 |
메모리 해제 | 자동으로 해제 | 명시적으로 해제 |
사용 범위 | 지역 변수: 선언된 블록 내 전역 변수: 프로그램 전체 |
프로그래머가 원하는 동안 |
메모리 관리 | 컴파일러의 책임 | 프로그래머의 책임 |
59.6 연습문제: 포인터 연산으로 메모리 주소 조작하기
다음 소스 코드를 완성하여 00000008과 00000014가 각 줄에 출력되게 만드세요.
#include <stdio.h>
int main()
{
int *numPtrA = NULL;
printf("%p\n", numPtrA_____);
printf("%p\n", numPtrA_____);
return 0;
}
정답
#include <stdio.h>
int main()
{
int *numPtrA = NULL;
printf("%p\n", numPtrA + 2); //데이터형이 int이므로 +1할 때마다 4바이트씩 증가한다.
printf("%p\n", numPtrA + 5);
return 0;
}
'C언어 > C언어 이론' 카테고리의 다른 글
[C언어] 문자가 숫자인지 아닌지 판별하기 - isdigit 함수 (0) | 2022.08.10 |
---|---|
[C언어] 문자열을 숫자로 변환하기 - atoi / atol / atoll / atof 함수 (0) | 2022.08.10 |
[C언어] 7주차 포인터의 활용 (0) | 2022.06.26 |
[C언어] 6주차 함수의 활용 (0) | 2022.06.25 |
[C언어] 6주차 구조체 (0) | 2022.05.27 |
Comments