메모리

- 실행 파일에는
코드 + 데이터 + bss 존재
- 프로그램이 메모리에
코드 + 데이터 + bss를 로드
- 프로그램이 실행하면서,
힙 + 스택을 동적으로 로드
- 운영체제가 메모리를 용도별로 나누면, 각 용도에 맞게 적절한 권한을 부여할 수 있다는 장점
- cpu는 메모리에 대해 권한이 부여된 행위만 할 수 있다. (r,w,x)
코드
- 실행가능한 기계 코드가 위치하는 영역
- 텍스트 세그먼트라고도 불린다.
- 프로그램이 동작하려면, 코드를 실행할 수 있어야 하므로, r,x 권한 부여
- w 권한은 공격자가 악의적인 코드를 삽입할 수 있으므로, 현대 OS에서는 w 권한 제거
데이터
- 컴파일 시점에 값이 정해진 전역변수, 전역 상수
- cpu가 이 세그먼트의 데이터를 읽을 수 있어야 하므로, r 권한 부여
- 데이터 세그먼트는 쓰기가 가능한 세그먼트와 쓰기가 불가능한 세그먼트로 분류
- 쓰기 가능 세그먼트: data 세그먼트
- 전역 변수와 같이 프로그램이 실행되면서 값이 변할 수 있는 데이터
- 쓰기 불가능 세그먼트: rodata (readonly data) 세그먼트
BSS
- 컴파일 시점에 값이 정해지지 않은 전역변수
- r,w 권한 부여
스택
- 스택 메모리 '크기'는 프로그램 빌드시 결정됨
- 컴파일 옵션으로 설정 가능
- clang windows에서 그냥 빌드하면 대략 1MB
- 스택의 메모리 위치는 실행 시 결정됨
값형으로 생성한 변수는 스택에 할당
스택은 빌드시 '크기'를 지정되어 있고 바로바로 이어서 할당하면 되기 때문에 힙보다 빠름
- 프로세스가 실행될 때, 이 프로세스가 얼만큼의 스택 프레임을 사용하게 될지 미리 계산 불가능
- OS는 프로세스를 시작할 때, 작은 크기의 스택 세그먼트를 먼저 할당하고 그때그때마다 확장한다.
- cpu가 자유롭게 값을 읽고 쓸 수 있어야 하므로, r,w 권한 부여
스택 오버플로
- 스택 크기가 1MB인데, 아래 처럼 하면 스택 오버플로 발생
int main(void)
{
char buf[1024*1024];
...
}
- 정해진 스택 메모리보다 많은 양을 사용하려하는 순간, 소유하지 않은 데이터를 접근하는 것은 매우 위험
- 위험하지만 조용히 넘어가는 경우도 있다.
- 좋은 개발툴을 쓰면 체크해주지만, 아닌 경우 실제 문제가 있지만 그냥 사용되는 경우도 있다.
힙
new(동적할당)으로 생성하면, 힙에 할당
- 메모리 누수 가능성
- 힙할당 요청 시, OS가 메모리 힙 영역에 빈공간을 찾아야하므로, 스택보다는 시간 소요
- 함수의 범위에 상관 없이 한동안 사용
- 데이터 크기를 컴파일 도중에 살 수 없어서, 동적할당
- 프로그램 실행 수명 보다는 짧은 시간 사용
- 헷갈리면 안되는게,
전역변수가 힙에 할당아님 (전역변수는 데이터 영역)
전역 변수
- 함수 밖에 선언: 전역
- 다른 소스코드파일에서 링크 가능
- 프로그램 실행 동안 공간 차지
- 데이터 영역에 들어간다.

전역 변수 에러 케이스
- 에러 케이스1
