본문 바로가기
Basic/C/C++

[C언어] 제 10 강 : 메모리 구조와 변수

by boxbop 2012. 1. 12.
반응형

 메모리 구조는 C언어를 공부하는데 아주 중요한 부분을 차지합니다. 포인터나 배열을 다룰때도 이러한 개념이 바탕이 되기때문에 피할 수 없는 부분인거죠...
피할 수 없으면 즐기는것이 자신이 원하고자 하는 바를 이룰 수 있게 하는 필수 요소입니다. 어떤분은 자신이 문제를 풀다가 틀리고, 모르는 부분이 나올때 희열감을 느낀다고 하더랍니다. 자신이 모르고 배워야하는 부분이 아직 남아 있다는 것을 느끼기 때문이라더군요... 존경스럽습니다....ㅠㅠㅠㅠ...

 여기서 메모리라고 함은 하드디스크, 램, 레지스터, 캐쉬를 포합니다. 그럼 이러한 모든 메모리를 이해해야되냐구요? 절대 아닙니다. 고맙게도 우리가 사용하는 운영체제는 이러한 메모리들을 통합하여 '가상 메모리'라는 가짜 메모리를 만들어줍니다. 즉, 가상 메모리 기법을 이용해서 복잡한 물리 메모리를 하나의 커다란 메모리로 보이게끔 하는 일은 담당하는 것이 운영체제라는 것이죠~ 따라서 앞으로 공부하면서 보게될 메모리 주소들은 운영체제가 만들어준 가상 메모리의 주소라는 것을 기억해두세요~

 가상 메모리의 영역??
가상 메모리는 큰 하나의 메모리로 구성되어 있다고 말씀드렸지만 이는 상당히 비효율 적입니다. 똑같이 30평의 집이 있을때 통째로 사용하느냐 아니면 방2개, 거실, 욕실등으로 나눠서 사용하느냐에 따른 효율성 문제인 것이죠~ 예를 잘못들었나...;;;;? 무튼 가상 메모리는 크게 4개의 영역으로 나뉩니다.

  코드  영역 : 실행할 프로그램의 코드를 저장한다.
데이터 영역 : 프로그램이 종료될 때까지 유지해야 할 데이터를 저장한다.
 스택  영역 : 임시적으로 사용하고 삭제할 데이터를 저장한다.
  힙    영역 : 프로그래머가 원하는 방식으로 사용할 수 있는 공간이다.

 코드 영역은 이름 그대로 실행할 프로그램의 코드가 저장되는 메모리 공간입니다. CPU는 코드 영역에 저장된 명령어들을 처리하는 방식으로 프로그램을 실행합니다.

 스택 영역에는 지역변수와 매개변수(인자)가 저장됩니다. 지역변수는 선언된 중괄호 안에서만 유효하고 매개변수는 함수가 호출되는 순간에 할당되기 때문이죠.

 데이터 영역에는 전역변수가 할당됩니다. 전역변수 같은 경우는 프로그램이 종료되기 전까지 사용하기 때문에 항상 유지를 해야되죠. 즉, 전역변수는 프로그램의 시작과 동시에 메모리 공간에 할당이 되어, 프로그램의 종료 시까지 메모리 공간에 남아있습니다. 참고로 전역변수의 선언은 코드가 메모리에 로드 된 이후에 처리되는 것이 아니고, 코드가 로드될때 같이 처리됩니다. 때문에 힙이나 스택 영역에서 사용하는 함수나 변수들을 이용해 초기화가 불가능 하므로 전역변수는 상수를 이용하여 초기화 해주어야 합니다.

 static이라는 키워드?
지역변수나 전역변수의 선언 앞에 static이라는 키워드를 붙이게 되면 정적 지역변수 또는 정적 전역변수가 됩니다. 이러한 static변수는 아주 유용한 기능을 제공하죠

int main(void)
{
    count();
    count();
    count();

    return 0;
 }

 void count (void)
 {
    static int cnt = 1;
    printf("count함수의 %d번째 호출.\n", cnt);
    cnt++;
 }

 출력값을 확인해보시면 1, 2, 3 번째 호출로 순서대로 증가하는 값을 보입니다. 만약 static이라는 키워드가 없다면? 계속 "count함수의 1번째 호출." 이라고만 출력이 되겠죠?

 static변수는 스택영역이 아닌 데이터 영역에 로드됩니다. 그렇다면 전역변수와 다를께 뭐가 있습니까? 위의 count함수가 코드영역으로 로드될때 static변수가 함께 로드되지 않습니다. static변수의 선언이 함수가 호출될 때마다 실행되는 것은 아니라는 이야기~~~이지만 흘려들으세요그냥.....;;;ㅎㅎㅎㅎㅎ 혹시라도 궁금하신분들을 위해.... 예를들어 

 static int number = function();

 이라는 코드가 존재한다고 합시다. 이러한 문장은 컴파일 에러를 발생키십니다. 왜냐면 static변수가 메모리 공간에 초기화 되는 시점과 함수 function()이 메모리 공간에 로드되는 시점이 동일하기 때문입니다. 

 static변수는 전역변수와 마찬가지로 데이터 영역에 로드되어 생존 기간은 둘 다 프로그램 종료 시까지 이지만 접근영역은 다릅니다. 전역변수는 언제 어디서나 접근가능하지만 static 지역변수 같은 경우에는 변수가 선언된 부분 안에서만 접근이 가능합니다.
 
 register라는 키워드?
register은 CPU 내에 존재하는 메모리 공간입니다. 메모리중 제일 빠른 메모리이죠. 그러나 레지스터의 공간은 아주 작습니다. regiter라는 키워드는 매개변수나 지역변수의 선언에만 사용이 가능합니다. 그렇다면 어떨때 사용을 할까요? 만약 지역변수인데 존재하는 기간이 아주 짧거나 어떠한 변수가 선언되어 있는 함수의 크기가 작지만 호출되는 빈도수가 많을때 사용합니다.

 register int number = 7;

 이렇게 사용합니다. 어렵지 않죠~? 사실 지금까지 레지스터 키워드를 자주 사용한 적도 없고 보지도 못해서 이정도에서 넘어가도록 하겠습니다.
반응형