2009-06-09 6 views
1

다음 기능에서 "레코드"유형의 크기를 가져 오려고합니다. 그러나 그것은 작동하지 않는 것 같다Delphi 7에서 포인터가 가리키는 유형의 크기를 가져올 수 있습니까?

function GetDataSize(P : Pointer) : Integer; 
begin 
    Result := SizeOf(P^); // **How to write the code?** 
end; 

예를 들어, 다음 레코드의 크기는

SampleRecord = record 
Age1 : Integer; 
Age2 : Integer; 
end; 

그러나 GetDataSize(@a)는 항상 (A 물론 SampleRecord 유형의 변수입니다) 1 반환 8 바이트입니다. 어떻게해야합니까?

델파이 프로 시저가 있음을 알게되었습니다 프로 시저 새 (var P : 포인터) 메모리 블록을 할당 할 수있는 포인터는 P가 가리키는 타입의 크기에 해당합니다. 어떻게 크기를 얻을 수 있습니까?

답변

7

을 이유 New가 할당하는 메모리 양을 알고 New컴파일러이다 . 마법이 내장 된 언어, 그래서 컴파일러는 당신이 그것을 호출 볼 때,이 같은 뭔가를 다시 작성합니다.

여기
// New(foo); 
foo := System._New(SizeOf(foo^), TypeInfo(TypeOf(foo^))); 

TypeOf은 해설 목적으로 만들어 낸 델파이 기능입니다 컴파일러는 알고있다 모든 변수 선언의 위치를 ​​알고 있기 때문에 foo의 선언 된 유형 있습니다. _New의 구현을 System.pas에서 확인할 수 있습니다. 유사한 다시 쓰기가 Dispose에 대해 발생하므로 메모리를 해제하기 전에 어떤 종류의 마무리 작업을해야하는지 알고 있습니다.

변수 의 변수과 의 선언은 으로 컴파일 타임 개념입니다. 실행 시간에, 그들은 존재를 그만 둔다. 런타임에 포인터는 단지 주소 일뿐입니다. 그것이 가리키는 것의 유형은 컴파일 타임에 결정되었습니다. 유형은 무언가의 크기를 결정합니다.

크기가 다른 여러 항목에 대한 포인터를 허용하는 함수를 작성해야한다면 은 첫 번째 포인터가 가리키는 것을 설명하는 두 번째 매개 변수을 제공하면됩니다.

다른 질문 (예 : "How to know what type is a var")을 확인하십시오. 질문자는 주소에 대해서만 변수에 대한 자세한 정보를 결정하는 방법을 궁금해했습니다.

+0

@Rob, 세부 정보 주셔서 감사합니다, 나는 그것이 complier 마술이라고 생각합니다. 나는 또한 왜 "새로운"절차가 없는지 설명한다. – trudger

0

Delphi에는 메모리 관리자가 내장되어 있습니다. 나는 새로운이 힙 객체에 액세스 할 수 있으며 일부 포인터에 대해 블록 크기를 얻기 위해 HeapSize() (또는 비슷한 루틴)을 사용한다고 믿는다.

+0

메모리 관리자는 대체 가능하지만이 기능은 정의의 일부입니다. ansistrings 및 동적 배열과 같은 주요 기능은이 기능이 없으면 작동하지 않습니다. –

3

포인터가 포인터를 포인터로 가리킬 수 있으므로 생각할 수있는 컴파일러는 추측하고 검사 할 수 없으므로 포인터 유형의 변수를 사용하여 데이터 구조의 크기를 찾을 수 없습니다. 일부 정보 here을 읽을 수 있습니다.

2

포인터가 가리키는 레코드의 크기를 결정하는 안전한 방법은 없습니다. 그러나 포인터가 가리키는 메모리를 할당 한 경우 해당 메모리 블록의 크기를 요청할 수 있습니다. 하지만 다시 블록을 할당 했으므로 블록의 크기를 이미 알고 있어야합니다! Delphi 메모리 관리자는 할당 된 모든 메모리 블록을 추적합니다. 메모리 관리자의 정보를 사용하면 포인터가 메모리 블록의 시작을 가리키는 경우이 정보를 찾을 수 있습니다. 그러나 큰 메모리 블록을 할당하고 일부 데이터를로드하고 포인터가이 블록 내부의 일부 데이터를 가리키는 경우이 방법은 매우 신뢰할 수 없습니다.

또한 레코드에서 참조 된 유형 (동적 배열, 문자열, 클래스 등)을 사용하는 경우 크기 대신 참조 크기 (4 바이트)를 가져 오기 때문에 반환하는 크기는 여전히 사용할 수 없습니다 참조되는 데이터의

NEW() 명령은 크기를 얻기 위해 전달한 데이터 유형의 유형 정보 만 사용합니다. 이것이 정확히 어떻게되는지를 알기 위해서는 델파이 소스 코드를 확인하면됩니다. \ source \ Win32 \ rtl \ sys \ System.pas를 열고 "_New"를 검색하십시오. 소스 코드가 정말 복잡 할 수 있지만 (그것의 앞에 밑줄과 함께.이 소스 코드를 사용하여, 델파이가 메모리 할당을 처리하는 방법을 이해하는 데 도움이 될 수 있습니다.

관련 문제