메모리
변수는 하나의 값을 메모리에 저장한다. 그렇다면 변수들은 레터럴을 컴퓨터 메모리에 어떤 방식으로 저장할까?
앞에서 포스트한 것과 같이 컴퓨터는 모든 정보(문자, 영상,음악 등)을 숫자로 변환하여 저장한다. 16진수로 표현하는 경우도 많다. 2진수는 1bytes를 8자릿수로 나타낸다면 16진수는 2자릿수로 나타낼 수 잇기 떄문에 정보를 표현하기 유용하다.
` 11111111(2진수) - > 0xff (16진수)`
c언어에서 메모리에 접근하기 위해서는 ‘&’을 사용한다. ~의 주소의 뜻으로 사용된다.
반대로 ‘*‘은 ~으로 가서 레터럴을 가져오라는 뜻으로 사용된다.또한, *은 포인터 변수를 선언할 수도 있다.
char *p
의 경우 p는 char형식의 레터럴이 있는 주소를 가르키는 포인터이다. 즉, p에는 주소값이 저장한다. 포인터의 크기는 메모리의 크기와는 상관없이 운영체제에 의해 결정된다. 예를 들어 운영체제가 64bits면 포인트는 64bits의 메모리공간을 차지한다.
c언어에서 문자열은 문자의 배열이고 제일 첫번째 문자의 주소가 저장되어있다. 문자들은 연속적으로 메모리공간에 저장되어 있기 때문에 메모리주소+i값을 하면 문자열의 i번째 글자를 얻을 수 있다.
1
2
3
4
5
6
7
8
9
10
#include <stdio.h>
int main(void){
char *s = "Heesu"
printf("%c\n",*(s)) //H
printf("%c\n",*(s+1)) //e
printf("%c\n",*(s+2))//e
printf("%c\n",*(s+3))//s
printf("%c\n",*(s+4))//u
}
따라서 문자열을 비교할 때 ==을 사용해서는 안된다. 문자열은 각각 다른 메모리에 저장된다. 따라서 ==을 사용하면 문자열의 레터럴값은 같더라도 문자열의 주소값을 비교하기 떄문에 False가 반환될 수 있다.
메모리
메모리 공간은 코드, 데이터, 힙, 스택
으로 구성된다.
코드영역에는 프로그램이 실행 될때 프로그램이 컴파일된 바이너리가 저장된다.
데이터영역에는 프로그램 안에 저장된 전역 변수가 저장된다.
힙영역에는 malloc으로 할당된 메모리의 데이터가 저장된다. 아래쪽을 향하여 메모리가 쌓인다.
스택영역에는 프로그램 내의 함수와 같은 것들이 저장된다. 위쪽을 향하여 메모리가 쌓인다.
메모리 누수를 줄이고 한정된 메모리 안에서 데이터를 공유하여 메모리 사용량을 줄여 효율적으로 사용하기 위해 메모리 영역을 나눈다. 모든 데이터들이 정렬되어있지 않고 섞여있다면 찾는 데에도 시간이 들고 남은 부분의 메모리 공간을 사용하기도 힘들기 때문이다.
힙은 아래방향으로 스택은 윗방향으로 메모리가 쌓이는데 이런 방식으로 메모리가 늘어나다보면 제한된 메모리 용량을 넘을 때가 있다. 이를 힙 오버플로우, 스택 오버플로우라 한다.
Comments powered by Disqus.