메모리 동적 할당
메모리 정/동적 할당의 개념과 동적할당함수의 기능과 사용법, 메모리 관리 함수.
- 학습 목표
- 메모리 정적할당과 동적할당의 이해.
- 메모리 동적할당함수를 이용하여 프로그램 작성.
- 메모리 관리함수의 기능 이해.
주요 용어
- 데이터 영역 : 전역변수와 static 변수가 저장되는 기억공간 영역.
- 힙(heap) 영역 : 프로그래머의 필요에 의해 할당과 소멸이 이루어지는 기억공간 영역.
- 스택(stack) 영역 : 지역변수와 매개변수가 저장되는 기억공간 영역.
- 메모리 정적할당 : 프로그램이 작성되는 단계에서 기억공간의 크기가 결정되는 기억공간 확보방법.
- 메모리 동적할당 : 프로그램이 실행되는 중에 입력되는 자료에 따라 기억공간의 크기를 결정할 수 있는 기억공간 확보방법.
메모리 동적할당의 개념
C 언어에서의 기억공간?
- 프로그램의 실행을 위해 기억공간 필요.
- 기억공간은 운영체제에서 할당.
- 할당되는 기억공간의 영역.
- 데이터 영역.
- 전역변수와 static 변수가 저장되는 영역.
- 프로그램이 시작하면서 할당되고, 종료하면 소멸하게 됨.
- 힙 영역
- 개발자의 필요에 의해 할당/소멸이 이루어지는 영역.
- 프로그램이 실행되는 중에 크기가 변함.
- 메모리 동적 할당에 사용되는 영역.
- 스택 영역
- 지역변수와 매개변수가 저장되는 영역.
- 함수 호출이 완료되면 사라짐.
- 데이터 영역.
기억공간의 확보
메모리 정적 할당(Static Allocation)
- 기억공간의 데이터 영역과 스택 영역 이용.
- 프로그램을 작성하는 단계에서 필요한 기억공간의 크기를 결정.
메모리 동적 할장(Dynamic Allocation)
- 기억공간의 힙 영역 이용.
- 프로그램 실행 중에 입력되는 자료에 맞게끔 기억공간의 크기를 결정.
메모리 정적할당
- 변수 선언이나 배열 선언과 같이 프로그램을 작성하는 단계에서 필요한 기억 공간의 크기를 결정.
- 변수 선언과 같이 할당 시켜줘야 할 기억공간의 한계 크기를 명확히 알고 있을 경우 사용.
- 메모리 정적 할당은 프로그램이 시작될 때 미리 기억공간의 크기를 고정하여 할당.
메모리 정적할당의 예
#include <stdio.h>
void test1(int);
void test2(int);
// 전역변수로 선언되어 데이터 영역에 할당.
// 프로그램 종료될 때까지 존재.
int a = 100;
void main()
{
// 지역변수로 스택 영역에 할당.
// main()가 종료될 때까지 존재.
int b = a;
test1(b);
test2(b);
}
// test1이 호출되면,
// 매개변수 c와 지역변수 d는 스택영역에 할당.
// test1이 종료되면 c, d는 지워짐.
void test1(int c)
{
int d;
d = c + 10;
printf("%d\n", d);
}
// test2가 호출되면,
// 매개변수 e와 지역변수 f는 스택영역에 할당.
// 종료되면 d, f는 지워짐.
void test2(int e)
{
int f;
f = e + 20;
printf("%d\n", f);
}
// main()가 종료되면 스택영역에 할당된 b도 제거.
// 프로그램이 끝아면 a도 제거.
메모리 정적할당의 장/단점
- 장점
- 프로그램에서 사용하게 될 변수의 기억 공간의 크기를 명확히 알고 있다면,
메모리 정정할당은 쉽게 기억 공간을 사용할 수 있고, 에러의 발생 확률을 줄일 수 있음.
- 프로그램에서 사용하게 될 변수의 기억 공간의 크기를 명확히 알고 있다면,
- 단점
- 사용하게 될 기억 공간의 크기를 정확히 알지 못하거나, 사용되는 자료의 크기가 각각 차이가 심하다면,
기억공간의 낭비를 가져오게 됨.
- 사용하게 될 기억 공간의 크기를 정확히 알지 못하거나, 사용되는 자료의 크기가 각각 차이가 심하다면,
메모리 정적할당의 문제점
#include <stdio.h>
void main()
{
int size;
// 배열의 크기를 변수로 선언하면 에러 발생?
char a[size];
printf("입력할 문자열의 크기? : ");
scanf("%d", &size);
printf("주소 : ");
scanf("%s", a);
printf("입력된 주소 %s\n", a);
}
#include <stdio.h>
#include <stdlib.h>
void main()
{
int size;
char *a;
printf("입력할 문자열의 크기? : ");
scanf("%d", &size);
// 메모리 동적할당.
a = (char *)malloc(sizeof(char) * size);
printf("주소 : ");
scanf("%s", a);
printf("입력된 주소 %s\n", a);
free(a);
}
메모리 동적할당 함수
malloc(), calloc(), realloc(), free() 등
메모리 동적할당의 장/단점
- 힙 영역을 이용하여 프로그램 실행 중에 입력되는 자료의 크기에 맞게 기억 공간 확보.
- 많은 자료를 처리하는 배열의 크기를 실행 시간에 정의해야 하는 경우에 유용.
- 프로그램 실행 시 기억 공간의 크기를 지정/재조정 가능.
- 시간이 지체되는 단점.
메모리 동적할당 순서
- 기억공간을 동적으로 할당 받을 변수를 포인터를 이용하여 선언.
- malloc() 등을 이용하여 기억공간을 동적으로 할당 가능.
- 기억공간의 사용이 끝나면 free()를 이용하여 기억공간 해제.
malloc()
- 인자로 할당 받고자 하는 기억 공간의 크기를 byte 단위로 전달.
- 힙 영역에 그 크기만큼 기억 공간을 할당, 할당한 기억공간의 첫 번째 주소 반환.
- void*로 명시하여 어떤 형이든 형 변환 가능.
- 초기화 안됨(기억공간의 초기화를 위해서는 memset() 사용).
- 형식 : void * malloc(size_t, number_of_bytes);
- 기능 : number_of_bytes에서 주어지는 크기만큼 기억 공간을 동적으로 할당.
- 예 : void * malloc(sizeof(int));
free()
- 메모리 해제 함수.
- 힙 영역에 할당된 공간은 프로그램이 종료될 때까지 유지됨.
- 할당된 기억 공간을 해제하지 않으면, 공간 부족 현상 발생.
- 명시적인 반남.
- 형식 : void free(void *p);
- 기능 : 동적으로 할당된 기억 공간을 해제할 때 사용.
메모리 동적할당 예 - 1
#include <stdio.h>
#include <stdlib.h>
void main()
{
// 1) 동적할당을 위한 포인터변수 선언.
int *a;
// 2) 기억공간 할당,
// - (int *)는 왼쪽의 포인터변수 a와 자료형을 일치시키기 위한
// 강제 형변환.
a = (int *)malloc(sizeof(int));
if (a == NULL)
{
puts("FAILLURE OF ALLOCATION!");
exit(1);
}
*a = 20;
printf("VARIABLE a : %d\n", *a);
// 3) 할당받은 기억공간 해제.
free(a);
}
메모리 동적할당 예 - 2
#include <stdio.h>
#include <stdlib.h>
#pragma warning(disable : 4996)
void main()
{
// 입력받을 문자 수 저장 변수 선언.
int size;
// 1) 동적 할당된 기억공간을 연결할 포인터.
char *str;
printf("INSERT SIZE OF STRING : ");
scanf("%d", &size);
// 2) 입력 받을 문자 수(size + 1)에 맞게 동적 할당.
str = (char *)malloc(size + 1);
if (str == NULL)
{
puts("FAILLURE OF ALLOCATION!");
exit(1);
}
printf("INSERT STRING : ");
// 동적으로 할당된 기억공간에 문자열 저장.
scanf("%s", str);
printf("STRING THAT SAVED AT DYNAMIC MEMORY : \n%s\n", str);
// 3) 할당받은 기억공간 해제.
free(str);
}
calloc()
- malloc()와 동일하게 힙 영역에 기억공간 할당.
- 사용하는 형태와 할당된 기억 공간을 0으로 초기화.
- 형식 : void * calloc( int n, int size );
- 기능 : 주어진 size의 크기를 갖는 기억 공간 n개를 할당.
- 예 : void * calloc( n, sizeof(int));
#include <stdio.h>
#include <stdlib.h>
void main()
{
int i;
int *a;
// int형 크기의 기억공간 5개 할당.
a = (int *)calloc(5, sizeof(int));
for (i = 0; i < 5; i++)
{
// 0으로 초기화 되어 있음.
printf("%d\n", a[i]);
}
free(a);
}
realloc()
- 이미 할당 받은 기억 공간의 크기를 변경해야 할 필요가 있을 때 사용.
- 형식 : void * realloc( void *p, int size);
- 기능 : 포인터 p가 가리키고 있는 기억공간의 크기를 지정된 size의 크기로 변경.
int *a;
// int형 크기의 5개 기억공간 할당.
a = (int *)calloc(5, sizefo(int));
...
// int형 크기의 10개 기억공간 재할당.
a = (int *) realloc(a, 10 * sizeof(int));
기억공간 관리함수
memcmp(), memcpy(), memset()
memcmp()
- 기억 공간에 들어 있는 자료를 주어지는 크기만큼 비교하여, 같은지 여부를 알 수 있게 해주는 함수.
- 형식 : int memcmp( void *s1, void *s2, size_t n);
- 기능 : s1, s2가 가리키고 있는 기억 공간의 내용을 n byte 만큼 비교.
- n바이트만큼 비교하여 s1 > s2 면 양수, s1 < s2 면 음수, s1 == s2 면 0 반환.
#include <stdio.h>
// 기억공간 관리함수를 위한 헤더파일.
// #include <mem.h>
#include <memory.h>
void main() {
char *s1 = "aaa";
char *s2 = "bbb";
int stat;
stat = memcmp(s1, s2, 3);
printf("%d\n", stat);
}
memcpy()
- 기억 공간의 자료를 다른 기억 공간 영역으로 복사하기 위한 함수.
- 형식 : void * memcpy( void *dest, const void * src, size_t n);
- 기능 : src에서 n byte만큼 dest에 복사.
#include <stdio.h>
#include <memory.h>
#include <string.h>
void main()
{
char src[] = "1234567890";
char dest[] = "abcdefghijklmnopqrstuvwxyz";
char *stat;
printf("BEFORE MEMCPY() DEST : %s\n", dest);
// src의 첫 부분에서부터 문자열의 길이(strlen())만큼의 자료를 dest에 복사.
stat = (char *)memcpy(dest, src, strlen(src));
if (stat)
printf("AFTER MEMCPY() DEST : %s\n", dest);
else
printf("FAILURE ON MEMCPY()!");
}
// BEFORE MEMCPY() DEST : abcdefghijklmnopqrstuvwxyz
// AFTER MEMCPY() DEST : 1234567890klmnopqrstuvwxyz
memset()
- 기억 공간의 자료를 지정한 문자로 채우는 함수.
- 할당된 기억 공간의 초기화나 내용 삭제를 위해 주로 사용.
- 형식 : void * memset( void *s, int c, size_t n );
- 기능 : 포인터 s가 가리키는 곳을 c 값으로 n byte 만큼 채운다.
#include <stdio.h>
#include <memory.h>
#include <string.h>
void main()
{
char s[] = "1234567890";
printf("BEFORE MEMSET() : %s\n", s);
// 배열 s의 데이커를 *로 길이 만큼 채움.
memset(s, '*', strlen(s));
printf("AFTER MEMSET() : %s\n", s);
}
'Language > C' 카테고리의 다른 글
[C] 파일 처리 함수 - 2 (0) | 2021.01.02 |
---|---|
[C] 파일 처리 함수 - 1 (0) | 2021.01.01 |
[C] 구조체와 공용체 - 2 (0) | 2021.01.01 |
[C] 구조체와 공용체 -1 (0) | 2020.12.27 |
[C] 배열과 포인터 - 3 (0) | 2020.12.27 |