전역변수와 지역변수로 해결이 되지 않는 상황
malloc은 메모리공간을 할당할 때 사용하는 함수 [잠시 변수 할당]
1. 지역변수일 경우
ReadUserName : 이름을 입력받고 입력받은 이름을 반환하는 함수
main : ReadUserName의 주소값을 반환해 출력
-> 문자열을 입력받기 위한 메모리 공간이 필요하다.
작동 순서
1. 메모리 공간 할당
2. 입력
3. 반환
-> name2의 출력이 끝났을 때
name1이 가리키는 것 : 첫번째로 입력한 문자열
name2가 가리키는 것 : 두번째로 입력한 문자열
-> ReadUserName()을 name1에 반환
-> name은 지역변수이므로 return과 동시에 소멸한다.
-> name1에는 소멸된 변수를 가리킨다. [에러 : 출력은 될수도 있지만 잘못된 코드]
2. 전역변수일 경우
ReadUserName 함수
1. 전역변수 name
2. gets
3. return
-> 전역변수는 고정 [삭제, 추가 불가]
-> name1과 name2을 입력받으면 두 개의 메모리공간 할당해야하지만
하나의 메모리 공간을 공유한다.
-> 출력을 하면 name1을 덮어써서 name1과 name2과 같아진다.
해결 방법
=>어떤 형태의 메모리 할당이 필요할까?
ReadUserName이 여러번 호출될때 각각 메모리가 할당되는 방법
함수가 호출되었을 때 메모리공간이 할당이 되어서 원하는 시간에 지울 수 있는 방법
: malloc()
-> 프로그래머가 지우지 않는 이상 계속해서 메모리에 남아있다.
데이터 영역 : 전역 변수
힙 영역 : 프로그래머가 원하는 시점에 할당과 해제하는 변수
스택 영역 : 지역 변수
#include <stdlib.h>
void* malloc(size_t size); //힙 영역으로의 메모리 공간 할당
void free(void * ptr); //힙 영역에 할당된 메모리 공간 해제
int main(void)
{
void* ptr1= malloc(4);
void* ptr2= malloc(12);
...
free(ptr1);
free(ptr2);
...
}
-> 포인터연산을 하기 위해서는 데이터형변환이 필요하다
*ptr1= 20을 하기위해서는
int* ptr=(int *) ptr1;
*ptr1 = 20;
malloc 함수의 반환형이 void형 포인터인 이유
void* ptr1=malloc(sizeof(int)); //4
void* ptr2=malloc(sizeof(double)); //8
void* ptr3=malloc(sizeof(int)*7); //28 //7개 변수의 배열
void* ptr4=malloc(sizeof(double)); //72 //9개 변수의 배열
int* ptr1=(int*)malloc(sizeof(int));
double* ptr2=(double *)malloc(sizeof(double));
int* ptr3=(int*)malloc(sizeof(int)*7);
double* ptr4=(double *)sizeof(double)*9);
-> malloc함수는 메모리의 용도를 모르기 때문에 포인터형의 결정을 못한다.
-> 형변환 과정을 통해 할당된 메모리의 주소값을 저장
힙 영역으로의 접근
int main(void)
{
int* ptr1=(int *)malloc(sizeof(int));
int* ptr2=(int *)malloc(sizeof(int)*7);
int i;
*ptr1=20;
for(i=0; i<7; i++)
ptr2[i]=i+1;
printf("%d \n", *ptr1);
for(i=0; i<7; i++)
printf("%d ", ptr2[i]);
free(ptr1);
free(ptr2);
return 0;
}
-> 힙 영역으로의 접근은 포인터를 통해서만 이루어진다.
int* ptr=(int*) malloc(sizeof(int));
if(ptr==NULL)
{
//메모리 할당 실패에 따른 오류의 처리
}
-> malloc 호출 후 반환된 주소값이 NULL이 아닌지 확인 후 메모리 공간을 사용해야 한다.
동적 할당인 이유
: 컴파일 시 할당에 필요한 메모리 공간이 계산되지 않고, 실행 시 할당에 필요한 메모리 공간이 계산되므로 동적할당
free 함수를 호출하지 않으면
: 할당된 메모리 공간은 메모리라는 중요한 리소스를 계속 차지하게 된다.
-> 프로그램이 종료되면 할당된 메모리가 소멸된다. [종료시 모든 리소스는 소멸된다.]
꼭 free함수를 호출해야 하는 이유는 무엇인가?
: fopen 함수와 쌍을 이루어 fclose 함수를 호출하는 것과 유사하다.
malloc을 호출하면 반드시 free 호출을 해야한다.
문자열 반환 함수 해결
char* ReadUserName(void)
{
char* name=(char *)malloc(sizeof(char)*30);
printf("What's your name? ");
gets(name);
return name;
}
int main(void)
{
char* name1;
char* name2;
name1=ReadUserName();
printf("name1: %s \n", name1);
name2=ReadUserName();
printf("name1: %s \n", name2);
printf("again name1: %s \n", name1);
printf("again name2: %s \n", name2);
free(name1);
free(name2);
return 0;
}
1. 메모리 할당 -> 함수를 빠져나가도 소멸되지 않는다.
2. 입력
3. 반환
calloc & realloc
-> malloc, calloc, realloc 함수 호출을 통해서 할당된 메모리 공간은 모두 free 함수호출을 통해서 해제한다.
'Programming > C' 카테고리의 다른 글
[C언어] 25장-1. C언어의 메모리 구조 (0) | 2021.04.14 |
---|---|
[C언어] 프로젝트 7. 동물 뒤집기 (0) | 2020.12.29 |
[C언어] 프로젝트 6. 물고기 키우기 (0) | 2020.12.28 |
[C언어] 프로젝트 5. 아빠는 대머리 게임 (0) | 2020.12.24 |
[C언어] 프로젝트 4. 비밀번호 마스터 (0) | 2020.12.24 |