2014-04-08 6 views
2

의 레코드에 메모리를 올바르게 할당/해제했습니다. 어제 메모리 손상이 발생했으며 일부 레코드 배열이 할당 및 할당 해제되는 방법에 대해 많은 의구심을 갖고 있습니다. 이것은 demostration에 대한 짧은 버전입니다 :고정 배열

type 
    TMyRecord = record 
    W: word; 
    S: String; 
    end; 

    TMyRecordArray = array [1 .. 315] of TMyRecord; 
    TArrayPointer = ^TMyRecordArray; 

var 
PageBase: TArrayPointer; 

procedure TTestForm.FormCreate(Sender: TObject); 
var 
    iRecord: TMyRecord; 
begin 
    PageBase := AllocMem(SizeOf(TMyRecordArray)); 
    iRecord.W := 1; 
    iRecord.S := 'TEST'; 
    PageBase^[1] := iRecord; 
end; 

procedure TTestForm.FormDestroy(Sender: TObject); 
begin 
    PageBase^[1] := Default (TMyRecord); 
    FreeMem(TPageBase); 
end; 

나는이 일을 제대로하지 않을 것이라고 확신합니다, 어떤 제안이라도 인정 될 것입니다.

답변

7

먼저 말할 코드가 작동한다는 것입니다. 누수없이 올바르게 마무리 및 할당 해제됩니다. 그래서 나는 당신의 질문에 좀 더 일반적으로 대답하려고 노력할 것입니다.

문자열은 관리되는 형식이며 컴파일러는 NewDispose을 관리하기 위해 특수 메모리 할당 루틴을 사용해야합니다.

New(PageBase); 

으로 할당과 함께 할당 해제 :

Dispose(PageBase); 

New에 대한 호출이 관리하는 모든 구성원이 기본 초기화되도록합니다. 그리고 다른 방향으로 Dispose은 관리 대상 회원을 확정합니다.

코드를 시도 할 때 수동으로이 작업을 수행 할 수 있습니다. 그러나 실제 코드에서는 배열의 모든 요소를 ​​마무리해야합니다. 코드는 하나만 완성합니다. 물론, 그것은 또한 오직 하나만 초기화하고 질문에 서면 그것은 괜찮습니다. 아마도 귀하의 짧은 버전의 질문은 단순화되어 지금까지 오류가 제거되었습니다.

그러나 관리되는 유형을 수동으로 처리하지 않는 것이 좋습니다. 이를 위해서는 NewDispose을 사용하십시오.

동적 배열은 여기에서 훨씬 간단 할 것입니다. 동적 배열을 사용하면 컴파일러가 모든 할당 및 할당 해제를 처리하고 모든 관리되는 유형을 올바르게 처리 할 수 ​​있습니다.

+0

감사합니다. 매우 유익합니다. – Walter78

+0

멋진 답변 + 1 –