델파이 포인터 (Pointer) 7편
procedure TForm1.MyProcedure;
var
AStr : ^string;
begin
AStr^ := 'SAMPLE';
ShowMessage(AStr^);
end;
위의 예제는 AStr이 메모리에 할당되지 않아서
에러가 난다고했습니다.
그렇다면 메모리에 어떻게 할당을 해야 할까요?
New라고 하는 함수(프로시져임)를 사용합니다.
델파이 New함수는 도움말을 보시면 아시겠지만
동적변수(포인터의 값을 의미)에 포인터를 할당하는 함수 입니다.
그러니까 위의 예제를 에러가 나지않도록 하려면
다음과 같이 한줄 추가 하면 되겠네요.
procedure TForm1.MyProcedure;
var
AStr : ^string;
begin
New(AStr); {<-- 추가된 부분}
AStr^ := 'SAMPLE';
ShowMessage(AStr^);
end;
이렇게 하면 군소리 없이 실행됩니다.
이렇게 할당된 포인터는해제 시킬 수도 있습니다.
물론 해제 시키는 함수를 사용해야지요.
그 함수의 이름은 Dispose입니다.
위의 예제에 한줄 더 추가해 보죠.
procedure TForm1.MyProcedure;
var
AStr : ^string;
begin
New(AStr);
AStr^ := 'SAMPLE';
ShowMessage(AStr^);
Dispose(AStr); {<-- 추가된 부분}
end;
이렇게 행을 추가 하면 할당된 포인터가
메모리에서 깜쪽같이 해제 됩니다.
그 이후에 다시 메모리에 할당 시켜야 겠지요.
앞에 게제된 설명에서 포인터의 형에 대한 얘기를 했었습니다.
PChar, PWORD와 같은 포인터 형과 ^Integer, ^string과 같은
일반적인 자료형에 ^를 붙여서 포인터 형으로 사용 하는 것말이지요.
그런데 사실은 이외에 또 한가지가 있답니다.
바로 Pointer라는 형입니다.
Pointer 라는 형은 마치 일반적인 자료형중에 Variant와 같은
성질의 포인터 자료형이라고 보면 될겁니다.
Variant라는 괴물자료형이 어떤 자료형의 변수도 대입이 가능한 형이라면,
Pointer 형은 어떤 포인터도 대입이 가능한 포인터 형이라고 할 수 있지요.
말로 설명하면 어려우므로 예제를 한번 보죠.
procedure TForm1.MyProcedure;
var
SS : string;
I1, I2 : Integer;
PP : Pointer; {<-- Pointer 형으로 선언됨}
begin
SS := eSOURCE.Text;
PP := @SS; {<-- PP가 String의 포인터 형으로 사용됨}
ShowMessage(string(PP^));
I1 := 1;
PP := @II;
I2 := Integer(PP^); {<-- PP가 Integer의 포인터 형으로 사용됨}
ShowMessage(IntToStr(I2));
end;
예제를 봐도 어렵군요. 호호호 하지만 자세히 들여다 보면
하나도 어렵지 않습니다.
먼저 PP라고 하는 포인터 형이 선언되었음을 알 수 있습니다.
세줄 내려가면 PP에 string의 포인터가 대입되었음을 알 수 있죠.
그래서 메세지로 보여줍니다. 그리고 세줄 더 내려가면 세상에나...
PP에 이번에는 integer의 포인터가 적용되는군요.. 쩝..
그리고 그 값을 메세지로 또 보여줍니다.
완전히 괴짜 포인터 형이군요. 허허허.
이 포인터 형을 사용하게되면 어떤 자료형을 사용할까에 대한
고민이 다소 해소될 것 같죠?
그러나... 여러분은 이곳을 주의 깊게 보셔야 합니다.
procedure TForm1.MyProcedure;
var
SS : string;
I1, I2 : Integer;
PP : Pointer;
begin
SS := eSOURCE.Text;
PP := @SS;
ShowMessage(string(PP^)); {<-- 바로 여기 }
I1 := 1;
PP := @II;
I2 := Integer(PP^); {<-- 그리고 또 여기}
ShowMessage(IntToStr(I2));
end;
무엇인고 하니, 바로 형변환이 필요하다 이겁니다.
처음에 값을대입할 때는 아무 걱정없이 마구사용 했을 지라도
그 값을 다시꺼내 쓸 때에는 이처럼 형 변환이 필요하다는 겁니다.
거져먹기는없다는 것이죠.
우리는 위에서 아주 유용할 것 같은(?) 자료형인 Pointer 형을 알아 보았습니다.
당장 사용은 안 하더라도 알아두면 좋겠죠.
앞에서 우리는 New와 Dispose 함수를 사용하여 포인터를
메모리에 할당하고 해제하는 방법을 배웠습니다.
그치만 프로그램머들은 포인터를 메모리에 할당할 때와
해제 할 때 GetMem함수와 FreeMem함수도 사용합니다.
아래 예제에서 처럼 말이죠.
procedure TForm1.MyProcedure;
var
SS : string; PP : Pointer;
begin
SS := 'SAMPLE';
GetMem(PP, SizeOf(PP)); {<-- 메모리에 할당}
Move(SS, PP^, SizeOf(PP));
ShowMessage(string(PP^));
FreeMem(PP);
end;
먼저 GetMem 함수를 이용하여 포인터 변수인
PP를 메모리에 할당하는 군요.
여기서 SizeOf라는 함수가 보이지요?
이 함수는 변수에 대한 크기를 복귀하는함수입니다.
GetMem 함수를 이용하려면 포인터의 크기를 알고 있어야 합니다.
그래서 SizeOf함수를 이용해서 PP의 크기를 알 수 있지요.
그 밑에는 Move함수를 이용하여 SS의 값을 PP^에 대입하는 군요.
procedure TForm1.MyProcedure;
var
SS : string; PP : Pointer;
begin
SS := 'SAMPLE';
GetMem(PP, SizeOf(PP));
Move(SS, PP^, SizeOf(PP)); {<-- 여기 }
ShowMessage(string(PP^));
FreeMem(PP);
end;
그런데 왜 PP^ := SS 라고 하지 않고
Move함수를 사용했을까요?
그건 아직 PP의 자료형이 정해져 있지 않기 때문입니다.
그러니까 Move함수를 통해 SS의 값을 PP^로 대입하는 겁니다.
그리고 타입캐스팅(형변환)을 하여서 메세지로 보여줄 수 있겠죠.
그리고 사용한 포인터는 반드시 해제해 줍시다.
여기서는 FreeMem 함수를 사용했군요.
이처럼 변수를 생성했다가 해제해 주는 것이 동적으로 이루어지기 때문에
포인터를 동적변수라고도 합니다.
메모리의 절약 차원에서 아주 바람직하겠지요?
8편계속...
'Delphi > 문법' 카테고리의 다른 글
델파이 포인터 (Pointer) 9편 (0) | 2023.08.22 |
---|---|
델파이 포인터 (Pointer) 8편 (0) | 2023.08.21 |
델파이 포인터 (Pointer) 6편 (0) | 2023.08.10 |
델파이 포인터 (Pointer) 5편 (0) | 2023.08.09 |
델파이 포인터 (Pointer) 4편 (0) | 2023.08.08 |
댓글