C언어를 잘하고 싶다면 메모리 구조에 대한 이해는 꼭 필요합니다. 물론 다른 언어도 마찬가지지만 메모리에 대한 조작이 비교적 많은 C언어는 메모리 구조는 바로 언어에 대한 이해도를 높여줍니다.
C언어로 짠 프로그램이 메모리에 어떻게 로드 되는지 알아보겠습니다.
다음 코드는 주의 깊게 안보셔도 됩니다.
완전 쓸데없는 노가다입니다. 흑 ㅠ
코드를 분석할 필요는 없고, 결과를 보려고 만든 코드니 결과만 알면 됩니다.
변수들의 선언 방식과 위치에 따라서 주소값이 어떤 규칙성이 보일 듯 하죠? 4로 시작하는 주소가 많고, 2,6으로 시작하는 주소도 보이네요. 대충 3개 정도로 나뉘어 보입니다.
실제로는 5개의 영역입니다.
일반적으로 텍스트 영역이 낮은 주소-> 스택영역으로 갈수록 높은주소, 스택을 제외한 나머지 주소는 낮은 주소에서 높은 주소값으로 데이터를 저장합니다.
텍스트, 데이터,bss, 힙, 스택 의 5개의 영역입니다.
텍스트 세그먼트(코드 세그먼트)
이 영역은 작성한 코드가 기계어로 바뀌어 저장 됩니다. EIP는 이 코드의 흐름을 읽는 EIP레지스터입니다. 이 곳에는 변수가 아닌 순수 코드만 있는 영역입니다.(함수, 제어문 등등..)
함수의 주소값이 4200으로 시작하는군요. 우선 아래 영역들의 주소값을 알아보고 비교하겠습니다.
데이터 세그먼트
초기화된 전역, 정적 변수가 저장되는 곳입니다. 위 코드의 실행 결과 화면에서 초기화된 전역, 정적변수의 주소를 찾아보면
b1,b2, d1,d2,d3 입니다. 주소가 4210로 시작합니다. 동일한 세그먼트에 저장됨을 알 수 있습니다.
bss 세그먼트
초기화 되지 않은 정적,전역변수는 모두 4223으로 시작하는 주소값을 가졌습니다.
여기까지 주소값의 영역을 정리하면 4200xxx->4210xxx->4223xxx (코드->데이타->bss) 로 위 그림과 동일함을 알 수 있습니다.
또한, 변수 선언 순서에 따라 주소값이 커지는 구조입니다.
힙과 스택 세그먼트
동적할당을 하여 힙 영역을 살펴본 결과 여기서는 6으로 시작하는 주소값을 가졌습니다.할당 순서에 따라서 주소값이 커지네요.
그런데 스택영역은 2로 시작합니다.
위 그림과는 일치하지는 않습니다. 단지 스택이 높은 주소에서 낮은 주소로 쌓여가는 것은 맞네요.
제 짧은 지식으로는 잘 모르겠군요. 추측하면, 메모리 모델의 차이라고 생각합니다.
사실 일반적인 프로그래밍을 하는 경우 이런 부분이 크게 필요한 부분은 아니기 때문에, 그러려니 하고 넘어 가겠습니다.
const 선언시
모든 전역 const 변수는 데이타 세그먼트에 저장됩니다.
지역 const 변수일 경우 문자열은 데이타 세그먼트에 저장되고, int 형 변수(double...도 마찬가지)는 스택에 저장됩니다.
다음은 이에대한 부연 설명입니다.
문자열을 바꿔가며 a포인터로 가르킵니다.
"abc"문자열에서 "xyx" 을가르키고 다시 "abc"를 가르킵니다.
결과를 보면..
"abc"를 가르키는 경우 주소값이 같습니다.
숫자의 경우와 달리 "abc"라는 문자열 값은 그 자체로 데이타 세그먼트에 저장되어 코드내에서 동일한 문자열이 사용되면 그대로 재사용되어 집니다.
char* b="abc"; 라는 코드를 추가하여 b가 가르키는 주소 값을 출력해 보면 a 가 가르키는 값과 같음을 알 수 있습니다.
코드 내에서 사용된 문자열 값은 데이타 세그먼트에 저장됩니다.
그래서 어떤 경우에도 데이타 세그먼트에 저장됩니다.
대략 알아본 메모리 구조입니다. 생각보다 별것 없습니다.
동적할당의 경우 좀 헷갈려 하시는 분도 계시는데, 포인터는 스택에 저장됩니다. 동적할당되는 영역이 힙인 것입니다.
다시 말해 스택에 있는 포인터가 힙에 있는 할당영역을 가르키는 것입니다.
메모리 구조를 알아야하는 가장 중요한 토픽 중 하나입니다.
이 부분에 관해서는 주제를 잡아야 되겠군요.