동적 메모리는 프로그램 실행시간에 메모리를 할당 받아 사용합니다. 말 그래도 '동적메모리'입니다. 프로그램 실행시에 사용자가 직접 필요한 메모리를 생성하고 프로그램 실행시 사용자가 직접 삭제할 수 있습니다. 보통 프로그램 중 가장 많은 메모리 공간을 사용합니다.
동적 메모리는 Heap 영역에 생성되며 저장소 키워드나 변수가 따로 존재 않고 malloc()함수를 사용하여 메모리 할당 후 주소를 이용한 메모리 접근 방식을 사용합니다.
- 동적 메모리 할당
malloc() 함수 사용 - 몇 가지 함수가 더 있지만 응용함수 일뿐 모두 malloc()함수의
확장형태입니다.
-
동적 메모리 삭제
free() 함수 사용
가장 간단한 예제
#include <stdio.h>
#include <stdlib.h>
void main( )
{
int *pn;
pn = malloc( 4 ); // 할당
*pn = 10;
printf("%d\n", *pn);
free( pn ); // 삭제
}
- 10
malloc()함수는 인자로 메모리 할당할 byte를 받아 생성한 동적메모리의 주소를 반환합니다. 그러므로 주소를 저장하기 위한 포인터변수가 있어야 합니다. 또 free()함수는 삭제할 메모리의 시작주소를 인자로 받아 메모리를 삭제합니다. int *pn은 auto 변수이므로 main()함수 시작과 함께 stack 메모리에 생성됩니다. 그리고 실행중 malloc()함수는 동적메모리를 생성하고 free()함수는 동적메모리를 삭제합니다.
위 예제를 아래 그림으로 다시 설명해 볼까요?
malloc()함수가 동적메모리의 메모리 할당 후 시작주소를 반환하므로 포인터 변수 pn에 저장합니다. 동적메모리 4byte를 할당하고 int형 메모리로 사용하기 위해서 int형 포인터 변수 pn에 주소를 저장합니다. free()함수는 삭제할 주소를 인자로 전달하므로 pn을 전달하면 동적메모리 4byte를 삭제합니다. 그리고 동적메모리의 이름은 *pn을 사용하여 접근할 수 있습니다. 만약 4byte를 char형 4개로 사용하려면 char형 포인터에 저장하고 []연산자를 이용하여 메모리를 접근할 수 있습니다. []연산자 기억나지죠? 배열에서 연습했습니다.
위 예제에서 malloc()함수의 인자 4는 숫자이므로 의미전달이 쉽지 않습니다. int형 메모리 1개를 생성하는지? char형 메모리 4개를 생성하는지? short형 메모리 2개를 생성하는지? 직관적이지 못합니다. (이와 같은 숫자를 매직넘버라 합니다. ㅡㅡ;; 코에 걸면 코걸이, 귀에 걸면 귀걸이 - 코드는 가독,명확성이 생명이므로 절대 사용하지 말라는 이야기입니다)
다음 예제는 sizeof()연산자를 사용합니다.
{
int *pn;
pn = (int*)malloc( sizeof(int) );
*pn = 10;
printf("%d\n", *pn);
free( pn );
}
- 10
sizeof(int)는 4값이므로 그 전 예제와 같습니다. 하지만 가독성도 좋을 뿐더러 혹 컴파일마다 int형 크기가 달라도 크게 문제되지 않습니다. 또 malloc()의 반환타입이 void*라, 대입하고자 하는 자료형(pn) int*로 형변환했습니다. 지금은 그냥 그렇게 해야한다고 알아두세요. 아니하면 컴파일러에 따라 워닝이나 에러가 발생합니다. 자세한 내용은 다음에 공부합니다.
다음은 double 크기의 동적메모리를 생성하고 사용하는 예제입니다.
void main( )
{
double *pn;
pn = (double*)malloc( sizeof(double) );
*pn = 10;
printf("%g\n", *pn);
free( pn );
}
- 10
간단하므로 설명은 생략!
다음은 int형 배열을 생성하고 사용하는 예제입니다.
{
int arr[5];
int i;
for( i = 0 ; i < 5 ; i++)
arr[i] = (i+1)*10;
for( i = 0 ; i < 5 ; i++)
printf("%d\n", arr[i]);
}
- 10
20
30
40
50
위 예제는 stack에 int형 배열을 생성했으며 정적배열이라고 합니다. 컴파일 시간에 크기가 결정됩니다. 배열의 크기는 상수만을 사용해야합니다.
위 예제의 메모리 표현 그림
위 예제는 아래 처럼 동적메모리를 사용할 수 있습니다.
{
int *arr;
int i;
arr = malloc( sizeof(int) * 5 );
for( i = 0 ; i < 5 ; i++)
arr[i] = (i+1)*10;
for( i = 0 ; i < 5 ; i++)
printf("%d\n", arr[i]);
free( arr );
}
- 10
20
30
40
50
위 예제는 heap에 생성되며 동적배열이라고 합니다. 실행 시간에 크기를 결정할 수 있습니다. 배열의 크기는 변수를 사용할 수 있습니다.
결과는 모두 아래와 같습니다.
위 예제의 메모리 그림
아래 예제 처럼 배열의 크기를 변수로 입력받아 결정할 수 있습니다.
void main( )
{
int *arr;
int i;
int num;
scanf("%d", &num);
if( num < 1 || 100 < num)
return;
arr = malloc( sizeof(int) * num );
for( i = 0 ; i < num ; i++)
arr[i] = (i+1)*10;
for( i = 0 ; i < num ; i++)
printf("%d\n", arr[i]);
free( arr );
}
- 10
20
30
40
50
입력이 5라면 결과는 같습니다.
'Windows Developer > C' 카테고리의 다른 글
[C] main(int argc, char *argv[])에서 포인터를 쓰는 이유? (0) | 2010.08.01 |
---|---|
[C] 재귀함수 (0) | 2010.07.20 |
[C] call by value와 call by reference (0) | 2010.07.17 |
[C]포인터의 장점 (0) | 2010.07.17 |