본문 바로가기

컴퓨터/언어,프로그래밍

C언어 :: 이중포인터 동적할당 해제에 관해서..

#include <stdio.h>
#include <stdlib.h> /*malloc 과 calloc ,free가 있는 함수*/

void main(void){
 int x,y,i,j;
 int **b;    /*   b[][]과 *b[] 로 하면 왜 안될까 */ 
 
 printf("몇행 몇열까지 넣을꺼삼?");
 scanf("%d%d",&x,&y);
 
 b = (int**)malloc(sizeof(int*)*x);    /*   (int**)에서 int 옆에 *이 왜 두개있을까? 하나면 워닝뜸..  */ 
            /*   sizeof(int*)에서 *은 잇어도 되고 없어도 됨..왜?  */
                                       /*   int*의 뜻은 몰까?   */
 for( i = 0; i < x; ++i )
  b[i] = (int*)malloc(sizeof(int)*y);
 /*       b= (int*)malloc(sizeof(int)*x*y);    위에 3줄을 왜 이렇게 선언하면 안되나?  */

 for( i=0 ; i<x ; i++ ){
  for( j=0 ; j<y ; j++ ){
   printf("%d행 %d열 항목값을 넣어주세요",i+1,j+1);
   scanf("%d",&b[i][j]);
  }
 }
 printf("당신이 입력한 행렬의 값들은..아래와 같습니다.\n");
 for( i=0 ; i<x ; i++ )
  for(j=0;j<y;j++)
   printf("%d행%d열은 %d\n",i+1,j+1,b[i][j]);
 
 for( i=0; i<x; ++i ){
  free(b[i]);
 }


 free(b); /*  왜 이거 하나만 쓰면 안되고 위에 for돌려가면서 free를 해야되나?  */

}

-----------------------------------------------------------------------

1. int** b;

 

지금 하고자 하는게 동적 할당이지 않습니까?

b[ ] [ ] 나 *b[ ] 로 선언하는 것은.. 초기화가 함께 이루어져야 합니다..

대괄호 안을 생략가능하게 하는 것이 초기화이기 때문이죠..

궂이 b[2][3]; 이런식으로 선언한다고 합시다..

그러면 이 문장은 이미 int 형 사이즈 3*2 개의 메모리가 스택에 할당되어 버리죠..

이건 동적할당이 아닙니다.. 정적할당이죠..

동적할당이란 런타임에 힙에 메모리를 할당하여 주소를 포인터 변수에 넘겨줌으로써

메모리를 사용하는 것입니다.

그러므로 int **b; 로 선언하는것이 타당합니다.

 

2. b = (int**)malloc(sizeof(int*)*x);

 

malloc 이라는 함수의 리턴형은 void* 입니다..

형이 정해지지않은 포인터(주소값) 를 반환합니다.

b 라는 포인터 변수에 malloc 이 리턴한 값을 대입하고 있네요..

변수 b 의 타입이 뭘까요.. 위에서 선언한듯이 b 의 타입은 int** 형 입니다.

(int**) 형으로 형변환 하여 대입하여 주는게 타당하지요..

 

sizeof(int*) sizeof 연산자는 괄호안의 타입이나 변수의 크기를 바이트 단위의

정수값으로 리턴하여 줍니다.

*을 빼도 아무상관 없는 이유는 int 형도 4바이트이고 int* 형도 4바이트 이기 때문입니다.

그러나 의미상 x 개의 int* 형을 담을 수 있는 공간을 동적할당 하는 것이므로..

int* 이라고 쓰는 것이 맞지요..

int* 은 int 형 실제 데이터의 주소를 가리킬수 있는 포인터 변수의 데이터 타입입니다.

(int** 은 int형을 가리키는 포인터변수를 가리키는 포인터 변수의 데이터 타입이구요..^^)

 

3. /*       b= (int*)malloc(sizeof(int)*x*y);    위에 3줄을 왜 이렇게 선언하면 안되나?  */

질문하신 b= (int*)malloc(sizeof(int)*x*y); 의 의미를 살펴봅시다..

만약 b 가 int* 타입이라면 위 문장은 x*y 개의 원소를 갖는 1차원 배열을 선언한것이 되죠.

그러나 위 코드는 2차원배열로 사용하기 위해 2중포인터를 쓰는거 같은데요..

즉.. b 는 int* 타입의 데이터들이 x 개 나열된 메모리공간의 시작주소를 가지고 있고요..

b[0], b[1], ... , b[x - 1] 들은 또 각각 y 개의 int 형 데이터들이 나열된 공간의 주소를 가지고 있지요..

그래서!!!!

위에서는 sizeof(int*) 이고 아래는 sizeof(int) 이라고 한 것 입니다.

 

4. free(b[i]);

 

메모리 헤제를 이렇게 하는 이유는 위와 같아요..

동적으로 할당된 공간은 x*y 개의 연속된 공간이 아니고..

y개의 연속된 공간 할당을 x 번 만큼 한것 이기 때문이죠..

 

이해가 가셨나용???

제주삼다수, 2L,... 오뚜기 진라면 매운... 상하목장 유기농 흰... 남양 프렌치카페 카... 고려인삼유통 홍삼 ... 종근당건강 오메가3... 요이치 카링 유무선...