변수는 컴퓨터 메모리에 생성된다.
특정한 메모리 주소에 저장됨.
서식지정자 %p를 사용하고, 변수 앞에 &를 붙이면 주소를 구할 수 있음.
메모리 주소는 C언어에서 포인터 변수에 저장된다.
int *numPtr; 이런식으로 *을 사용해 선언함.
즉 포인터와 메모리 주소는 같은 의미임.
메모리의 특정 위치를 가리킬 때 사용한다.
변수가 int형이면 이 변수의 메모리 주소를 저장하는 포인트도 int *이어야한다.
시스템이 32비트인지 64비트인지에 따라 포인터의 크기가 달라짐.
(32비트에서는 4바이트, 64비트에서는 8바이트)
#include <stdio.h>
int main()
{
int *numPtr; // 포인터 변수 선언
int num1 = 10; // 정수형 변수를 선언하고 10 저장
numPtr = &num1; // num1의 메모리 주소를 포인터 변수에 저장
printf("%d\n", *numPtr); // 10: 역참조 연산자로 num1의 메모리 주소에 접근하여 값을 가져옴
return 0;
}
역참조 연산자 *은 포인터에 저장된 메모리주소로 이동해 값을 가져옴.
numPtr : 변수가 위치한 메모리 주소를 가리킴.
*numPtr: 메모리 주소안에 있는 값을 가져옴.
(*은 선언할 때와 역참조 둘다 사용됨. 다른 역할.)
#include <stdio.h>
int main()
{
int *numPtr; // 포인터 변수 선언
int num1 = 10; // 정수형 변수를 선언하고 10 저장
numPtr = &num1; // num1의 메모리 주소를 포인터 변수에 저장
*numPtr = 20; // 역참조 연산자로 메모리 주소에 접근하여 20을 저장
printf("%d\n", *numPtr); // 20: 역참조 연산자로 메모리 주소에 접근하여 값을 가져옴
printf("%d\n", num1); // 20: 실제 num1의 값도 바뀜
return 0;
}
*numPtr = 20; 으로 가리키고 있던 &num1의 메모리주소 안에 있는 값을 20으로 바꿔줌.
void포인터? -> 자료형이 정해지지 않음. 어떤 자료형이든 저장 가능. 범용 포인터.
직접 자료형을 변환하지 않아도 암시적으로 자료형이 변환됨.
하지만 자료형이 정해지지 않아 역참조가 불가능함.
그럼 왜 씀. 다양한 자료형으로 포인터에 저장할 때나 자료형을 숨기고 싶을 때 사용.
이중 포인터
int **numPtr2;
*을 두 개 사용하면 이중 포인터다.
왜사용? 포인터의 메모리 주소는 일반 포인터에 저장할 수 없어서 이중 포인터에 저장해야함.
#include <stdio.h>
int main()
{
int *numPtr1; // 단일 포인터 선언
int **numPtr2; // 이중 포인터 선언
int num1 = 10;
numPtr1 = &num1; // num1의 메모리 주소 저장
numPtr2 = &numPtr1; // numPtr1의 메모리 주소 저장
printf("%d\n", **numPtr2); // 10: 포인터를 두 번 역참조하여 num1의 메모리 주소에 접근
return 0;
}
**numPtr2를 하면 &numPtr의 값인 &num1의 값을 참조해 10이 나오게됨.
포인터 주의사항.
잘못된 주소를 저장하면 에러남. 정상적인 메모리 주소면 직접 저장 가능.
int *numPtr = 0x00CCFC2C; // 실제로 존재하는 메모리 주소라면 저장할 수 있음
'System Hacking > Basics' 카테고리의 다른 글
Heap힙 /ptmalloc (0) | 2025.04.28 |
---|---|
malloc / 메모리사용 (0) | 2025.04.27 |
docker 명령어 (1) | 2025.04.27 |
컴파일(Compile), 링커(Linker) 정리함 (0) | 2025.04.24 |
pwndbg 명령어 다시 정리 (0) | 2025.04.03 |