[열혈C프로그래밍] chapter 22. 메모리 관리와 메모리의 동적 할당

chapter 22

메모리 관리와 메모리의 동적 할당

C언어의 메모리 구조: Code(코드), Data(데이터), Stack(스택), Heap(힙)

메모리를 나누는 이유: 메모리 공간을 나눠서 유사한 성향의 데이터를 묶어서 저장을 하면,
관리가 용이해지고 메모리의 접근 속도가 훨씬 향상되기 때문에 4가지 영역 Code,Data,Stack,Heap으로 나눈다.

메모리의 동적 할당

:특정 함수의 지역변수는 함수를 빠져나갈때 소멸되므로, 밖에서는 쓸 수 없다.
또 함수 밖으로 나가도 쓸수 있는 전역변수는 또 다시 사용하면 값이 유지가 안되기에 사용이 부적절하다.
따라서 함수 밖에서도 소멸되지않고, 또 값이 독자적으로 유지되는 변수가 필요한데, 그 변수가 바로
동적할당된 변수이다. malloc()을 통해 변수에게 동적으로 메모리를 할당해주고, 소멸시키고 싶을때 free()을 사용하여 개발자
마음대로 소멸시킬수 있는 변수, 동적할당된 변수가 바로 함수를 빠져나가도 소멸되지 않는 적절한 변수이다.

# include <stdio.h>
void * malloc(size_t size); // 힙(heap) 영역으로의 메모리 공간 할당
void free(void* ptr); // 힙(heap) 영역에 할당된 메모리 공간 해제
// malloc 함수는 성공 시 할당된 메모리의 주소값, 실패시 NULL 반환.

=> 자료형이 void* 인 이유: 동적할당할 변수의 자료형이 어떻게 될지 모르기에 void로 둔것이다.
이는 개발자가 casting으로 자료형을 변환시켜 주면 되는데 ,만약 하지 않으면 void
으로는 주소값만 할당될 뿐,
변수를 이용해 사용할 수 없으므로 반드시 casting 해야 함을 명심하자.

=> free 함수를 안쓰면?: 사실 free 함수를 안써도 프로그램이 종료되면 힙영역의 동적할당된 변수들도 소멸되기 때문에 메모리에 끝까지 남지 않는다.
하지만 free()를 안쓰면 복잡한 프로그램을 짤때 메모리 관련하여 무수한 에러가 생길 수 있으므로
동적할당을 선언했으면 반드시 free() 함수를 쓰도록 하자.

동적할당을 안 써서 오류 난 경우

# include <stdio.h>
# include <stdlib.h>

# define len 30

char* readname(void){
 
  char name[len];
  printf("이름 입력: ");
  fgets(name,len,stdin);

  return name; // 이러면 문제가 되는게 name이 지역변수이므로 함수가 종료될 때 name도 소멸된다. 
  // 그런데 반환은 name의 주소값이므로 아무리 main에 name의 주소값이 반환되더라도
  // name은 소멸되었므로 참조해도 오류가 난다. 그래서 세그멘테이션 오류가 나는 것이고(혹은 null 반환),
  // 이럴 때 malloc으로 동적할당하여 함수가 끝나도 사라지지않는 변수를 사용해야 하는 것이다.
}


int main(void){

  char* name1;
  name1=readname();
  printf("%s", name1);   


  return 0;
}

동적할당하여 제대로 된 경우

# include <stdio.h>
# include <stdlib.h>

# define len 30

char* readname(void){
 
  char* name=malloc(sizeof(char)*len);
  printf("이름 입력: ");
  fgets(name,len,stdin);

  return name; 
}


int main(void){

  char* name1;
  name1=readname(); // 동적할당을 하여 name이라는 변수가 힙에 계속남아있으므로 name1이 name의 주소값을 잘 반환받아,
  // 에러 없이 성공적으로 문자열을 출력할수 있다. 
  printf("%s", name1);   

  free(name1);// name,name1의  메모리 공간 해제

  return 0;
}