최근 하고 있는 것이 여러 뻘짓이다 보니 본이 아니게 3중 포인터를 쓰게 되더군요.

대략… 3차원 표현 이라던가…

2차원의 영역중, 각 픽셀의 갖고있는 간단한 값을 가져올 때, 안쓸꺼 같던것들이 자주 쓰이더군요.

일단 예제.. 여기서 예제는 int a[10][20][30] 과 같은 역활을 하는 동적 메모리 할당을 해봅니다.

일단 C언어부터…

// 만들때

int ***ptr;
ptr = (int ***)malloc(sizeof(int **) * 10);

for(i=0; i < 10; ++i)
{
    ptr[i] = (int **)malloc(sizeof(int *) * 20);   

    for(j=0; j < 20; ++j)
        ptr[i][j] = (int *)malloc(sizeof(int) * 30);
}

// 해제할때
for(i=0; i < 10; ++i)
{
    for(j=0; j < 20; ++j)
        free(ptr[i][j]);

    free(ptr[i]);
}

free(ptr);

그리고 C++, C++ 답게 new와 delete 명령어를 써서 (물론 위의 C방법으로 해도 상관없습니다.)

 

 //<!----- 3차원 배열 예제 -----//
//배열을 X,Y,Z에 각각 10,20,30 식 할당.
#define ARRAY_X  (10)
#define ARRAY_Y  (20)
#define ARRAY_Z  (30)
void main()
{
     //선언
     int ***ptr;
     //할당
     ptr = new int**[ARRAY_X];    //X차원 선언
     for(int i=0; i<ARRAY_X; ++i) {
         ptr[i] = new int *[ARRAY_Y];  //Y차원 선언
     } 
     for(int i=0; i<ARRAY_X; ++i){
         for(int j=0; j<ARRAY_Y; ++j) {
             ptr[i][j] = new int[ARRAY_Z]; //Z차원 선언
   
             for(int k=0; k<ARRAY_Z; ++k){
            //값을 씀.
                 ptr[i][j][k] = i*j*k;
             }
         }
    }
    // 해제할때, 역으로 Z부터 해제함.
    for(int i=0; i<ARRAY_X; ++i) {
        for(int j=0; j<ARRAY_Y; ++j) {
            for(int k=0; k<ARRAY_Z; ++k){
                printf("ptr[%d][%d][%d] = %d\n", i, j, k, ptr[i][j][k]);
            }
           delete [] ptr[i][j];  //Z차원 해제
        }
        printf("\n");
    }
    for(int i=0; i<ARRAY_X; ++i) {
        delete [] ptr[i];    //Y차원 해제
    }
    delete []ptr;      //X차원 해제
    return 0;
}

 마지막으로 Java ...
Java의 경우.. 포인터가 없죠;;
Java의 메모리는 C언어처럼 직접 건들이는 구조가 아니고,
물리적 메모리 공간과 별도로 여길 관리하는 메모리 관리자가 있습니다..(Virtual Machine(이하 VM)안에)
여기의 메모리 관리자가 알아서 할당합니다. (OS에서 자원 관리 하듯이라 생각하셔도 됩니다.)

즉 int a[10] 이라 하면, 내부적으로는 C언어처럼 malloc(sizeof(int) * 10)이 일어난다는거죠.
C언어적인 문법상으로 보면 그냥 정적 배열처럼 보이지만... 내부적으론 동적 배열 처리한다고 보시면 됩니다.

해제는.. 간단하게 null 해주면 VM의 메모리 관리자가 해당 영역을 없는 셈 칩니다.
(파일을 지울때 앞글자만 지워주고 없는셈 치는것과 같은 이치입니다)

완전히 메모리 상에서 지우고 싶을땐 가비지 컬렉터를 강제로 실행시켜줘야 하지만..
굳이 할필요는 없습니다.
만약 VM이 메모리 할당이 일어날때 더 이상 메모리가 없다면,
현재 사용되지 않는 메모리 할당자들,
즉 위의 null 처럼 되어있는것.. 이라던가, 클래스에서 나와 더이상 사용하지 않는 변수들 같은것들을
찾아 지워준뒤, Compaction등이 일어납니다. 그리고 빈곳에 메모리를 할당하죠.
개념은 이정도고 실제 작동원리나 자세한건 Java책을 참고하시기 바랍니다.

// 만들때
int ptr[][][] = null;
ptr = new int[10][20][30];

// 해제할때
ptr = null;
System.gc(); // 선택사항

전세계에서 제일 많이 사용하는 언어는 자바란 이유가.. 이런 편리함 때문일껍니다... T_T

C언어의 모토(motto)는
-> 어떤 머신이든 제어하는 언어를 만들자.
이지만,

Java의 모토(motto)는
-> 코딩은 1번, 코딩된 소스를 변형없이 모든 머신에서 돌아가는 프로그램을 만들자
라고 합니다.

실제... C언어는 ARM 계열이나. 리눅스의 GCC, MS의 Visual C++ ... 미묘하게 다릅니다.
int 의 경우만해도 보통은 4byte로 알고있지만, 사실은 해당 머신에서 숫자를 표현하기 적당한 공간을 뜻합니다.
무슨말이냐면
간단한 휴대폰의 경우 int의 할당은 2byte or 1byte 만 할당될수도 있고, PC에선 4byte, 서버나 과학용 컴퓨터에선 8byte 이상을 할당할수 있다는 얘기죠.
그게 무슨 대수냐..... 하실지도 모르지만.. 게임 만들다보면.. 이것까지 제어하는 부분까지.. orz

Java는.. int 는 4byte 라고 정해져 있습니다. 이건 어떤 머신이든 VM이 있다면 무족건 4byte로 쳐줍니다.

'C/C++언어' 카테고리의 다른 글

음 고정소수점 만들기..  (0) 2008.05.09
고정 소수점  (0) 2008.05.09
각 언어별 3중 포인터  (0) 2008.05.06
쉬프트 연산과 곱셈  (0) 2008.03.26
[리눅스프로그래밍] makefile  (1) 2008.03.07
ASSERT(), VERIFY(), TRACE()  (0) 2008.03.04

+ Recent posts