Nagie's DevStory

[C] 31. 다양한 포인터 ( 1 ) 본문

Programming/C

[C] 31. 다양한 포인터 ( 1 )

Nagie 2023. 10. 3. 23:15
728x90

기존에 공부했던 포인터뿐만 아니라 C에는 여러 가지 포인터가 있다.

 

//기본 포인터
int *pPtr;

//이중 포인터
int **ppPtr;

//배열 포인터
int (*pPtr)[3]; //열의 개수가 고정되어야함

//함수 포인터
int (*function)(int);

//void 포인터
void* pPtr;

//포인터 배열
int *pPtr[3];

 

1. 기본 포인터

 

우리가 제일 처음 공부했던 포인터다.

 

가장 많이 사용하며 해당 변수의 메모리 주소를 저장한다.

 

사용 방법은 아래와 같다.

 

int nVariable = 10;

int* pPtr = &nVariable;

 

2. 이중 포인터

 

이중 포인터에서부터 조금 헷갈리기 시작한다.

 

이중 포인터는 포인터의 메모리 주소를 저장하는 포인터다.

 

일반적인 이중포인터 사용방법

 

 

위의 사진처럼 순차적으로 그냥 참조할 뿐이다

 

다만 이런 형태를 자주 사용할 경우 논리 에러를 유발할 가능성이 커져

 

잘 사용하지는 않지만 열의 개수가 서로 다른 메모리(배열)를 다룰 때는 사용한다.

 

열의 개수가 서로 다른 메모리를 다룰때

 

아래는 이중 포인터를 이용해 열의 개수가 서로 다른 메모리를 사용하는 소스 코드다.

 

int** ppPtr = (int**)malloc(sizeof(int*) * 3); //행의 개수는 3개

ppPtr[0] (int*)malloc(sizeof(int) * 4); // 첫번째 행 열의 개수는 4개
ppPtr[1] (int*)malloc(sizeof(int) * 2); // 두번째 행 열의 개수는 2개
ppPtr[2] (int*)malloc(sizeof(int) * 3); // 세번째 행 열의 개수는 3개

 

선언 부는 위와 같이 작성할 수 있으며 접근 방법은 우리가 일반적으로 사용하는 배열처럼 접근하거나

 

포인터 산술연산으로 접근이 가능하다.

 

혹여나 위의 방법처럼 이중 포인터를 사용하는 게 이해가 잘되지 않는다면 도서관을 생각해 보면 이해가 빠를 거 같다.

 

행의 개수를 담당하는 아래의 코드는 

 

int** ppPtr = (int**)malloc(sizeof(int*) * 3); // 카테고리가 나눠진 책장

 

카테고리가 나눠진 책장의 개수를 생각하면 된다.

 

도서관에 가면 사회 , 인문 , 과학 , 역사 등등 책의 성향에 따라 분리를 시켜 여러 개의 책장으로 분할해 놓았으니 말이다.

 

그렇다면 아래의 코드는 뭘 의미하게 될까?

 

ppPtr[0] (int*)malloc(sizeof(int) * 4);
ppPtr[1] (int*)malloc(sizeof(int) * 2); 
ppPtr[2] (int*)malloc(sizeof(int) * 3);

 

그렇다 책장엔 책이 있어야 하니 당연히 책의 권수를 생각하면 이해가 빠르다.

 

도서관의 책이 아무리 잘 정리 되어있더라도

 

책장마다 책의 권수는 동일하지 않다는 특성을 생각해 보면 적절한 비유라고 생각한다.

 

그리고 이중 포인터를 이용해 동적 메모리를 할당받았다면 반드시 열에 해당하는 동적 메모리부터 해제시켜야 한다.

 

행에 해당하는 부분을 먼저 메모리 해제 시켜버리면

 

열에 해당하는 메모리에 접근할 방법이 사라져 메모리 공간에 가비지로 남게 된다.

 

int** ppPtr = (int**)malloc(sizeof(int*) * 3); //행의 개수는 3개

ppPtr[0] (int*)malloc(sizeof(int) * 4); // 첫번째 행 열의 개수는 4개
ppPtr[1] (int*)malloc(sizeof(int) * 2); // 두번째 행 열의 개수는 2개
ppPtr[2] (int*)malloc(sizeof(int) * 3); // 세번째 행 열의 개수는 3개


for(int free_idx = 0 ; free_idx < 3 ; free_idx++) { //열에 해당하는 메모리 해제

    free(ppPtr[free_idx]);
}

free(ppPtr); //행에 해당하는 메모리 해제

 

그러므로 반드시 위의 예시 코드처럼 메모리 해제를 해줘야 한다.

728x90
Comments