사전을 보자
pointer : 지시봉, 바늘

포인터는 "주소를 저장하는 변수"
하지만 그냥
앞으로 포인터를 "선언"한다 하는 것은 👆"지시봉"을 선언한다 생각하기!!
우리가 입주를 한다고 생각해보자
아파트 집 주소를 알아야 입주할 수 있다
이게 포인터 쏘EZ
int a = 10; = 입주할 가족
int* p = &a; = 집주소
*p = 이사 잘 했는지 확인
C언어 입장에서는
아파트의 구조 즉 메모리의 구조를 알 수 있고
어디에 누가 살고 저장되어있는지
이사를 보내고 입주를 시키고 마음대로 할 수 있음
예시를 통해 이해해보자

메모리 = 아파트 🏬
메모리 주소 = 아파트 호수 🔟
값 = 인원 수 👫
포인터 = 관리자 지시봉씨 👆
int a = 10;
int* p = &a;
int a = 10 : 아파트에 자료형 가족이 입주하는 것
int *p = &a : 자료형 가족을 관리하는 지시봉씨가 입주
따라서!
int a = 10
-> int형 가족 10명 입주할게요~
int b = 3
-> int형 가족 3명 입주할게요~
int* p = &a
-> 가족을 관리하는 관리자 지시봉씨 입주할게요~
!!포인터는 지시봉씨가 관리하는 가족의 집 주소를 저장하는 역할!!
&a (&주소 기호)
a의 집주소 = 105호
집주소 알려주세요~
a
집에 누가 있는지 알려주세요~
10명 있어요~
*p
방문 한번 해보겠습니다~
105호는 10명이 있습니다~
p
어디 집에 방문하나요?
105호에 방문합니다~
&p
지시봉씨 집주소는 어떻게 되나요?
저는 102호에 살고 있습니다!

*p = 5
이런. 오우 노
관리자지시봉씨가 int가족이 시끄럽다고 5명으로 줄여버렸어요 ㅠㅠ
**king = &p 헉!
(관)지시봉씨가 잘 하고 있나 관리하는 👆👆건물주지시봉씨가 입주 했어요
*king = &b
👆👆건물주지시봉씨가 (관)지시봉씨의 횡포를 보고 다른 집을 관리하도록 했어요
이제는 관리자 지시봉씨는 103호를 관리하게 되었어요
(관)지시봉씨가 관리하는 집을 바꾸고 싶을 때
👆👆건물주지시봉(이중포인터)를 통해 바꿔줘야 해요.
char* newRoom = malloc(sizeof(int));
char가족은 아파트에 입주하고 싶어 malloc 부동산에 가서 방 하나를 요청했습니다.
malloc부동산은 집을 얻어서 주소를 char가족에게 주었습니다.
우리는 그 집에 들어가고, 입주가 가능해졌습니다.
그런데!
char가족은 1년 뒤 다른 곳으로 이사를 갔습니다.
어머 근데 계약 해지를 안하고 가버렸네요?
ㅋㅋ 돈이 자꾸나와요
그래서
후다닥 free(newRoom)
집 비웠습니다! 계약 해지를 했습니다.
이것처럼 우리가 집을 계약 했다가 해지를 안하면 아주 큰일이 납니다.
그래서 꼭 집을 계약했다가. 이사가거나 방을 빼면 꼭 free 계약 해지를 해야합니다. 안 그러면 파산해요 -> 프로그램이 터져요
int* house = malloc(sizeof(int));
*house = 777;
777호 입주하겠습니다~
free(house);
방 정리하고 계약 해지합니다~
방이 너무 좁다 좁아
realloc님 저의 방 좀 넓여주세요
int* room = malloc(sizeof(int) * 3); // 3칸짜리 집
room = realloc(room, sizeof(int) * 6); // 6칸짜리 집으로 확장!
하지만 realloc씨는 씨크해서 넓혀보다가 안되면 새로운 집으로 줄 수도 있음
그래서 꼭
room = realloc(room, sizeof(int) * 6);
다시 주소를 받야함
!!리모델링 사기 주의!!
realloc씨는 확장 리모델링하다 실패하면 기존 집도 안 돌려줍니다.
int* temp = realloc(room, new_size);
if (temp != NULL) {
room = temp;
} else {
// 확장 실패 시 대처
}
그러니 꼭 보험을 들어둡시다.
이사를 해야하는데
하나하나 옮기기 귀찮네..
이삿짐 센터 부를게요~
int oldHouse[3] = {1, 2, 3};
int newHouse[3];
memcpy(newHouse, oldHouse, sizeof(oldHouse));
집만 준비해서 오면 그대로~ 이사를 진행해줍니다
포장이사죠.
이삿짐 센터가 쫌 시크해서
| 주의사항 | 설명 |
|---|---|
| ❌ 크기 초과 | size를 넘기면 다른 메모리 영역까지 복사 → 프로그램 터짐 |
| ❌ 겹치는 영역 | src, dest가 겹쳐 있으면 undefined behavior 발생 → 대신 memmove 써야 함 |
| ❌ 문자열 복사 실수 | strlen(src)까지만 복사하면 \0이 빠져서 문자열 잘림 현상 → +1 꼭 해줘야 함 |
| ❌ 타입 무시 | memcpy는 자료형 무시하고 메모리 복사만 하기 때문에 자바스크립트 같은 언어 감성으로 쓰면 파탄남 |
함수에서 변수 바꾸려면 포인터 쓰자.
void fire(int x) {
x = 0;
}
int home() {
int a = 10;
fire(a);
printf("%d\n", a); // 출력: 10 (불이 안꺼짐)
}
소방서를 부르는데 집 주소를 안주니까 불을 끌 수 없슴
void fire(int* x) {
*x = 0;
}
int home() {
int a = 10;
fire(a);
printf("%d\n", a); // 출력: 0 (불이 꺼짐)
}
꼭 집 주소를 보내주자
이 글에서 나온 개념들을 정확한 용어로 정리하면 아래와 같습니다.
필요한 키워드를 하나씩 검색해서 공부해보세요.
| 키워드 | 개념 설명 |
|---|---|
pointer | 메모리 주소를 저장하는 변수 |
*, & | 포인터 연산자 (*: 간접 참조, &: 주소 가져오기) |
| Call by Value vs Call by Reference | 함수 호출 방식: 값만 넘길지, 주소를 넘길지 |
malloc / free | 동적 메모리 할당 / 해제 (heap 메모리 사용) |
realloc | 기존 메모리 확장 / 재배치 (주소 변경 가능성 있음) |
memcpy / memmove | 메모리 복사 (포인터 배열이나 구조체 복사 시 사용) |
| Function Pointer | 함수를 가리키는 포인터 (함수도 메모리에 있음!) |
| Pointer to Pointer | 포인터를 가리키는 포인터 (이중 포인터) |
| Dangling Pointer | 이미 해제된 주소를 가리키는 포인터 (위험!) |
| Memory Leak | 할당한 메모리를 해제하지 않아 생기는 누수 |
| Stack vs Heap | 자동 메모리와 동적 메모리의 차이 |
| Value vs Reference Semantics | 값 복사인지 참조 복사인지의 의미적 차이 |
포인터는 주소를 사용하는 방식.
주소를 잘 알려줘야
이사도 하고, 입주도 하고, 소방서도 출동이 된다.