[C언어] 8. 메모리관리와 메모리 동적할당
제가 책(윤성우의 열혈 C 프로그래밍)을 보다가 까먹었던 부분만 포스팅 하는 것입니다!
순서가 뒤죽박죽이어도 이해해주세요~~!
C언어의 메모리 구조
프로그램 실행 시 운영체제에 의해서 마련되는 메모리 구조는 다음과 같습니다.
코드영역: 실행할 프로그램의 코드가 저장되는 메모리 공간
데이터영역: 전역변수와 static으로 선언되는 static 변수 할당
이 영역에 할당되는 변수들은 프로그램의 시작과 동시에 메모리 공간에 할당되고,
프로그램 종료 시 까지 남아있게 됩니다.
스택영역: 지역변수와 매개변수 할당
이 영역에 할당되는 변수들은 선언된 함수를 빠져나가면 소멸됩니다.
힙 영역: 데이터, 스택 영역에 할당되는 변수들은
생성과 소멸의 시점이 이미 결정되어 있습니다.
그래서 C언어에서는 프로그래머가 원하는 시점에 변수를 할당하고 소멸하도록 지원하는데,
이러한 유형의 변수들은 이 힙 영역에 할당됩니다.
메모리의 동적 할당
전역변수와 지역변수로 해결이 되지 않는 상황을 보겠습니다.
함수를 이용해서 사용자의 이름을 저장하고 싶은 것인데요~
첫번째는 지역변수를 사용한 경우입니다
#include <stdio.h>
//이름을 저장해서 반환하는 함수
char* your_name(void)
{
char name[30]; //지역변수로 선언
printf("이름을 입력하세요:");
gets(name);
return name;
}
int main(void)
{
char * name1;
name1=your_name();
printf("%s",name);
return 0;
}
위의 경우는 에러를 발생시키는데,
그 이유는 함수 your_name을 빠져나오면서 그 안의 선언된 지역변수들은
모두 소멸되어서 name1에는 쓰레기 값이 저장되기 때문입니다.
그렇다면 전역변수를 사용하면 문제가 해결될까요?
#include <stdio.h>
char name[30]; //전역변수로 선언
char* your_name(void)
{
printf("이름을 입력하세요:");
gets(name);
return name;
}
int main(void)
{
char* name1;
char* name2;
name1=your_name();
name2=your_name();
printf("%s",name1);
return 0;
}
전역변수를 사용하면 위의 경우와 같이 여러명의 이름을 받을 때,
다른 이름을 덮어쓰는 문제가 발생합니다.
이를 해결해주는 것이 힙 영역에 할당되는 변수입니다.
힙 영역의 메모리 공간 할당과 해제는 malloc과 free함수로 할 수 있습니다.
#include <stdlib.h>
int *ptr=(int *)malloc(sizeof(int)*7); //동적할당
free(ptr); //동적해제
그리고 malloc함수를 선언했으면 꼭 free함수로 동적해제를 해주어야합니다~!
그럼 아까 문제를 malloc을 써서 해결해보겠습니다.
#include <stdio.h>
char* your_name(void)
{
//동적할당
char * name=(char *)malloc(sizeof(char)*30);
printf("이름을 입력하세요:");
gets(name);
return name;
}
int main(void)
{
char* name1;
char* name2;
name1=your_name();
name2=your_name();
printf("%s",name1);
printf("%s",name2);
free(name1); //동적해제
free(name2);
return 0;
}
문제가 깔끔히 해결되는 것을 보실 수 있습니다~!
calloc과 realloc 함수
힙 영역에 메모리 공간을 할당하는 함수로 calloc이 있습니다.
#include <stdlib.h>
int * ptr=(int *)calloc(7,sizeof(int));
//인자만 다를 뿐 malloc과 동일합니다.
그리고 힙에 할당된 메모리 공간 확장 시에는 realloc 함수를 이용합니다~
#include <stdlib.h>
int main(void)
{
int *arr=(int *)malloc(sizeof(int)*3); //길이가 3인 int형 배열 할당
arr=(int *)realloc(arr,sizeof(int)*5); //길이가 5인 int형 배열로 확장
}