jun-wiki

View My GitHub Profile

Posts (Latest 10 updated) :
Read all
Contents:
  1. 포인터
    1. 정의
    2. & (Address-of 연산자)
    3. * (Dereference / Indirection 연산자)
    4. &과 *의 관계 예제
    5. 포인터 선언 & 초기화
    6. NULL 포인터
    7. 유의점
  2. 동적 메모리 할당 (Dynamic Memory Allocation)
    1. 특징
    2. 관련함수
      1. malloc
      2. calloc
      3. realloc
      4. free
    3. 유의점

포인터

정의

메모리 주소 저장하는 변수

일반 변수: 값 저장

포인터 변수: 값이 있는 위치(주소) 저장


& (Address-of 연산자)

변수의 메모리 주소를 가져옴

int a = 10;
printf("%p\n", &a); // a의 주소 출력


* (Dereference / Indirection 연산자)

포인터가 가리키는 주소의 값에 접근

int a = 10;
int *p = &a; // p는 a의 주소 저장
printf("%d\n", *p); // p가 가리키는 값(a) = 10
*p = 20; // a 값이 20으로 변경됨


&*의 관계 예제

int a = 100;
int *p = &a;   // p에 a의 주소 저장 (&)
printf("%d\n", *p); // p가 가리키는 값 출력 (*)


포인터 선언 & 초기화

int *ptr;        // int형 변수 주소 저장 가능
double *dptr;    // double형 변수 주소 저장 가능
char *cptr;      // char형 변수 주소 저장 가능


NULL 포인터

아무것도 가리키지 않는 포인터

int *p = NULL;
if (p == NULL) { /* 주소 없음 */ }


유의점

주의사항 설명 예시
1. 초기화 없이 사용 금지 선언만 하고 쓰면 쓰레기 주소 가리킴 → 크래시 int *p; *p = 10; // ❌
2. 해제 후 접근 금지 free 한 뒤 접근하면 댕글링 포인터 발생 free(p); printf("%d", *p); // ❌
3. 범위 밖 접근 금지 배열이나 할당 메모리 범위 초과 시 메모리 오염 arr[10] = 5; // ❌
4. 형(type) 일치 포인터 타입과 실제 데이터 타입 일치 필요 double *p; int a; p = &a; // ❌
5. NULL 체크 사용 전 if (p != NULL) 확인 if (p) printf("%d", *p);
6. 이중 포인터 주의 **pp는 두 번 역참조하므로 구조 정확히 이해 int **pp;



동적 메모리 할당 (Dynamic Memory Allocation)

특징

실행 중(runtime) 에 필요한 만큼 메모리 확보

정적 할당(static)과 달리 크기를 미리 몰라도 가능

C에서는 malloc, calloc, realloc, free 사용


관련함수

malloc

지정한 바이트 크기만큼 메모리 할당

초기화는 하지 않음 (쓰레기값)

int *arr = (int *)malloc(sizeof(int) * 5); // int 5개 공간



calloc

지정한 크기만큼 메모리 할당 + 0으로 초기화
쓰레기 치워줌

int *arr = (int *)calloc(5, sizeof(int));



realloc

기존 메모리 크기 변경

arr = (int *)realloc(arr, sizeof(int) * 10); // 10개로 확장



free

동적으로 할당한 메모리 해제

free(arr);
arr = NULL; // 해제 후 NULL로 설정 권장


유의점

메모리 할당 후 해제 필요
그렇지 않으면 쓸데 없이 메모리 점유하는 메모리 누수 발생

malloc의 경우 초기화하거나 하지 않을 경우
이전 데이터 남음

값을 다시 채우기전 (이전 값이 남아있을 때)
그 변수를 사용시 오작동

  • 예:
int *cnt = malloc(sizeof(int));
(*cnt)++; // 초기화 안 했는데 증가 → 예측 불가 결과

항상 먼저 덮어쓰거나 초기화 안할 경우 고려 필요




free를 통해 메모리 해제시 유의할 점

메모리 공간은 반환되지만 값은 남아 있다

-> 여전히 이전에 할당됐던 주소 가리킴

NULL을 사용 안할 경우:

  • 댕글링 포인터(헤제된 메모리 가리키는 포인터) 발생

    • 다른 데이터 덮어씌워 질 수 있음

    • 조용히 잘 있다가 크래쉬 터짐