|
자세히 답변을 드리겠습니다.
EXE 파일은 두가지 영역으로 나뉘어져 있는데,
[코드 영역]과 [데이터 영역] 입니다.
코드 영역은 말 그대로 프로그램의 코드를 기계어로 변역한 구간이며 이 구간에 작성된 프로그램의 흐름대로 프로그램은 실행되게 되어 있습니다. EXE 파일에 앞부분에 위치하게 되지요.
데이터 영역은 프로그램에서 사용된 상수, 문자열과 전역변수 등의 공간으로 힙(heap)과는 구별되는 전역 변수의 공간이 미리 할당되어 있습니다. 나중에 변수는 이 영역의 포인터만을 가지게 되지요. EXE 파일에 뒷부분에 위치합니다.
상수와 문자열의 경우에는 크게 문자가 되지 않는 정보 입니다만 전역변수, 특히 전역 배열의 경우에는 말씀하신 문제점을 불러올 수 있습니다. 왜냐하면 이 영역은 초기화가 되지 않기 때문이죠.
#include <stdio.h>
void main(void)
{
char *str = "ABCDEFG";
}
이러한 코드를 빌드 시킨 후에 EXE 파일 크기를 확인하세요. 그리고 EXE 파일을 열어보면 ABCDEFG 라는 문자열을 파일 끝부분에서 찾을 수 있습니다.
그리고 간단한 코드를 빌드 하더라도 실행 파일의 크기가 상당히 크다는 것을 알 수 있는데, 이것은 C/C++에서 쓰는 기본 라이브러리와 컴파일러 자체가 내부적으로 쓰는 정보들이 많기 때문에 이것들이 쓰는 문자열과 전역변수의 정보 때문 입니다.
어쟀든 위의 코드를 아래와 같이 변경하여 컴파일 해보세요.
#include <stdio.h>
char buffer[10240];
void main(void)
{
char *str = "ABCDEFG";
}
위의 코드를 빌드 시킨 후에 EXE 파일의 크기를 확인하세요.
처음에 작업한 내용과 용량이 10 킬로바이트 차이 나는 것을 확인할 수 있습니다.
바로 buffer라고 선언한 배열의 크기인 10 킬로바이트만큼 EXE 파일이 커진 것이죠.
하지만 아래와 같이 하면 용량이 증가되지 않습니다.
#include <stdio.h>
void main(void)
{
char buffer[10240];
char *str = "ABCDEFG";
}
바로 전역변수이냐 지역변수이냐의 차이인데요.
전역변수는 데이터(data) 영역에 생성이 되지만, 지역변수는 스택(stack)에 생성되기 때문에 EXE 파일에 미리 공간을 확보해놓지 않는 것 입니다.
그러면 동적 메모리를 할당(new나 malloc을 이용)하면 어디에 생성이 될까요~?
바로 힙(heap)에 생성이 되지요.
힙이란 프로그램의 데이터 영역과 구별되는 공간으로 시스템에 남아있는 메모리 영역을 말 합니다.
깊이 들어가면 운영체제론까지 나오게 생겼으므로 대충 각설하고...
왜 미리 데이터 영역을 EXE 파일에 넣어놓아서 프로그램 크기를 커지게 했을까요?
MS 프로그래머가 바보여서 그랬을까요? ^^?
바로 로딩(loading)을 빠르게 하기 위함이죠.
요즘같이 코어2듀오에 초당 수십기가를 전송하는 메모리를 쓰는 시대라면야 로딩 시간이 큰 문제가 아니지만 EXE 파일 규약은 DOS 시절부터 있던거라서 느린 CPU에 느린 메모리를 가지고 프로그램에서 쓰는 많은 메모리를 로딩시에 동적으로 할당하게되면 엄청난 시간 낭비가 뒤따랐을테니까요.
그래서 궁여지책으로 데이터 세그먼트(data segment) 영역을 EXE 파일에 쑤셔넣는 멋진 일을 해냈다고 봅니다. (어디까지나 제 생각)
그래서 결국 초기화 안된 메모리 영역에 쓰레기값이 들어가는 것처럼 EXE 파일에도 컴파일되는 시스템의 메모리에 남아있는 쓰레기값이 그대로 남아있게 됩니다.
이 값이 무슨 값이 될지는 그때 메모리에 남아있는 값에 따라서 달라지게 되므로 매번 빌드시마다 바뀌게 되어있는거죠.
결국 EXE 파일이 빌드 할때마다 틀려지는 사태가 생기게 됩니다.
문제가 되는 것은 내가 야한소설을 읽고 프로그램을 닫았을 때, 야한소설을 저장했던 메모리 영역이 빌드시에 컴파일러가 할당한 buffer[10240] 영역과 겹쳐서 EXE 파일 내부에 들어가는 것 입니다 ㅡㅡ; 상상하기 싫군요...
메모리를 할당했다가 해제한다고 메모리 내용이 초기화가 되는 것이 아니고 그냥 메모리에 남아있기 때문이죠.
컴파일러에 변수를 초기화하는 옵션을 본 것도 같은데 -_-;;; 기억이 잘나지 않네요 -_-;;;
도움이 되셨길 바랍니다.
|