개발자가 되기로 마음을 먹고 기본문법을 공부하던 중 포인터를 만났습니다.
포인터를 공부하던 중 의문점이 하나 생겼습니다.
"int는 4byte고 메모리 주소가 8byte면 도대체 메모리 주소는 어디에 저장되는 걸까?"
일단 우리가 본격적으로 메모리의 주소와 포인터를 이해하기 전 메모리가 몇 byte를 차지하는지 알아볼 것 입니다.
대부분의 글과 강의에서는 이를 다루지 않습니다. 이는 아마 대부분 안다루는 것은 중요하지 않거나 처음 배우때 필요없는 개념이기 떄문일 것입니다.
하지만 저는 궁금하니 알아볼 것 입니다!
일단 메모리 주소는 아키텍쳐마다 다릅니다.
우리가 흔히 쓰는 64비트 시스템 (x86_64 아키텍처)는 메모리 주소가 64bit로 8byte이고 32비트 시스템 (x86 아키텍처)같은 경우에는 메모리 주소가 32bit로 4byte입니다.
이를 각각 임이의 메모리 주소로 표현하면
--32bit--
16진법(0x) : 0x00400000;
2진수 : 0000 0000 0100 0000 0000 0000 0000 0000 (2진수, 32비트);
--64bit--
16진법(0x) : 0x0000000100000000;
2진수 : 0000 0000 0000 0000 0000 0000 0000 0001 0000 0000 0000 0000 0000 0000 0000 0000 (2진수, 64비트);
이런 식으로 표현할 수 있다.
우리는 이제 메모리의 주소의 크기를 알았습니다.
저는 개인적으로 제가 생각했던 것 보다 큰 크기였습니다.
이제 우리는 글의 시작 부분에 제가 처음으로 던졌던 의문을 해결하기 위한 지식을 갖추었습니다. 그럼 본격적으로 시작해봅시다!
일단 저의 의문! int a를 선언을 하면 메모리에 4byte만큼 데이터를 입력받은 공간을 만듭니다. 그럼 메모리 주소는 연속되는 4byt의 주소 중 첫번째 byte의 메모리 주소를 int a의 메모리 주소로 활용합니다.
예를 들어, int a가 0x1000이라면 0x1000 ,0x1001, 0x1002, 0x1003 이렇게 4byte의 걸쳐 저장됩니다.
그럼 이 메모리 주소들은 어디로 가는 걸까요?
일단 int a에 저장되지는 않습니다. int a는 데이터를 저장하기 위한 공간이지 메모리 주소를 저장하기 위한 공간이 아닙니다. 그리고 8byte의 메모리 주소를 받았을 경우에는 int a에 애초에 데이터를 담을 수 없습니다. int a는 4byte이기 때문이지요.
일단 메모리 주소는 운영체제와 CPU가 관리합니다.
주소자체는 CPU에 저장되지는 않습니다. CPU가 매번 int a의 주소를 사용한다해서 CPU에 저장된다는 의미는 아닙니다 CPU는 주소를 참조할 때마다 그 주소를 RAM이나 CPU내부의 레지스터에 일시적으로 저장하여 사용합니다.
예를 들어, 프로그램이 int a의 값을 읽거나 쓸 때 CPU는 그때마다 int a의 메모리 주소를 사용하여 해당 위치로 접근합니다.
만약 메모리 주소를 변수에 저장하고 싶다면 C++에서는 포인터를 사용합니다.
int a = 10;
//int 자료형의 가진 변수의 메모리 주소를 b에 받겠다.
int* b = &a;
이 포인터(int*)는 64bit(8byte)의 크기로 int a의 메모리 주소를 가집니다.
- 예를들어 int a라는 자료형이있습니다.
- 변수는 4byte 만큼 메모리에 공간을 확보하지만 자료형에 대한 정보는 저장하지 않습니다.
- 그렇기에 우리는 포인터를 생성하기 위해서 int* 같이 * 앞에 자료형을 써서 우리가 어떤 자료형을 가진 변수의 데이터를 불러오는지 알려주어야 합니다.
위 인용구가 잘 이해되지 않을 수 있습니다. 걱정마세요! 저도거든요...
자료형 같은 경우에는 메모리에 저장되지 않습니다. 대신 컴파일러가 a가 int임을 파악하고 이에 맞게 메모리 할당 및 연산을 진행합니다.
만약 제가 포인터가 가리키는 데이터에 자료형을 적어주지 않는다면 컴파일러는 해당 주소에 데이터가 어떤 자료형인지 알 수 없을 것 입니다. 그렇다면 제대로 된 연산을 할 수 없습니다.
int a와 같은 지역변수는 스택에 할당됩니다. 스택은 함수 호출시 자동으로 할당되고 함수가 끝나면 해제되는 메모리 영역입니다. 스택에 할당된 변수의 메모리 주소는 함수가 실행되는 동안 유효하며, CPU는 이 주소를 관리합니다.
- 변수는 메모리 주소와 자료형을 저장하지 않는다.
- 변수를 선언을 할 시 그 자료형에 맞게 메모리에 (n)byte 만큼 공간을 만들어 주는 것 뿐이다.
- 변수에는 자료형이나 메모리 주소가 담기지 않는다.
- 메모리 주소는 메모리에 만들어진 (n)byte 중 첫번째 공간의 주소를 쓴다.
- 0x1000 ,0x1001, 0x1002, 0x1003 이라면 0x1000이 주소이다.
- 메모리 주소는 아키텍쳐마다, 크기가 다르다
- (x86_64 아키텍처)는 8byte(64bit)
- (x86 아키텍처)는 4byte(32bit)
- 메모리 주소는 CPU가 int a를 참조할때 그 짧은 시간동안에만 레지스터에 저장한다.
처음쓴 블로그라 부족한 점이 많지만 앞으로도 잘 부탁드립니다.
포안