1-2 주 전에 "블록 헤더가 손상되었습니다."및 "블록이 해제 된 후 수정되었습니다."라는 오류가있었습니다.동적 배열을위한 메모리 할당 - 블록 헤더가 손상되었습니다. (FastMM4)
Somebody는 FullDebugModeScanMemoryPoolBeforeEveryOperation을 true로 설정하는 것에 대한 좋은 팁 (Alexander에게 감사함)을 주었고, 마지막으로 오류의 TRUE 위치가 어디인지에 대한 몇 가지 표시를했습니다.
오류 로그는 TScObj 개체를 가리 킵니다. 두 번째 객체는이 객체와 매우 유사하며 사용하면 오류가 나타나지 않습니다. 그래서 이것은 어떻게 든이 오류가이 특정 객체 (TScObj)에 있음을 확인합니다.
로그는 다음과 같이이다 :
FastMM has detected an error during a free block scan operation.
FastMM detected that a block has been modified after being freed.
Modified byte offsets (and lengths): 15656(1)
The previous block size was: 15672
This block was previously allocated by thread 0xC88, and the stack trace (return addresses) at the time was:
402EC9 [System][@ReallocMem]
40666C [System][DynArraySetLength]
40A17D [FastMM4][UpdateHeaderAndFooterCheckSums]
40674E [System][@DynArraySetLength]
4CE329 [ReadSC.pas][ReadSC][TScObj.ReadData][239]
4CDD0C [ReadSC.pas][ReadSC][TScObj.LoadFromFile][168]
4D013E [SmplCubImport.pas][SmplCubImport][TCubImport.ImportSample][164]
40461A [System][@AfterConstruction]
4DC151 [UnitAsmJob.pas][UnitAsmJob][TAsmJob.LoadSample][960]
The allocation number was: 78709
The block was previously freed by thread 0xC88, and the stack trace (return addresses) at the time was:
402E6F [System][@FreeMem]
4068A8 [System][@DynArrayClear]
405DF9 [System][@FinalizeArray]
4CE9F9 [ReadSC.pas][ReadSC][TScObj.ReadData][298]
4CDD0C [ReadSC.pas][ReadSC][TScObj.LoadFromFile][168]
4D013E [SmplCubImport.pas][SmplCubImport][TCubImport.ImportSample][164]
40461A [System][@AfterConstruction]
4DC151 [UnitAsmJob.pas][UnitAsmJob][TAsmJob.LoadSample][960]
것은 내가 내가 부당하게 메모리를 할당 할 수 있습니다 내 코드에서 어떤 장소를 볼 수 없다는 것입니다. 나중에 "부하 디스크에서"절차 동안
type
TWordTrace = array of Word;
TDiskTrc = array of Smallint;
var Tracea,Tracec: TWordTrace;
procedure TScObj.ReadData;
Var i: Integer;
DiskTrc1: TDiskTrc;
DiskTrc2: TDiskTrc;
DiskTrc3: TDiskTrc;
DiskTrc4: TDiskTrc;
begin
SetLength(DiskTrc1, H.NrOfSamples+1);
SetLength(DiskTrc2, H.NrOfSamples+1);
SetLength(DiskTrc3, H.NrOfSamples+1);
SetLength(DiskTrc4, H.NrOfSamples+1); <------ log shows error here. <- on DynArraySetLength
FStream.Seek(H.SOffset, soFromBeginning);
if H.SampleSize = 1 then
begin
for i:= 1 TO H.NrOfSamples DO
FStream.Read(DiskTrc1[i], 1);
Unpack(DiskTrc1);
for i:= 1 TO H.NrOfSamples DO
FStream.Read(DiskTrc2[i], 1);
Unpack(DiskTrc2);
etc...
end
else
begin
for i:= 1 TO H.NrOfSamples DO
begin
FStream.Read(DiskTrc1[i], 2);
DiskTrc1[i]:= Swap(DiskTrc1[i]);
end;
Unpack(DiskTrc1);
for i:= 1 TO H.NrOfSamples DO
begin
FStream.Read(DiskTrc2[i], 2);
DiskTrc2[i]:= Swap(DiskTrc2[i]);
end;
Unpack(DiskTrc2);
etc...
end;
SetLength(Tracea, H.NrOfSamples+1);
SetLength(Tracec, H.NrOfSamples+1);
SetLength(Traceg, H.NrOfSamples+1);
SetLength(Tracet, H.NrOfSamples+1); <------ log shows error here. <- on FinalizeArray
for i:=1 to H.NrOfSamples DO
begin
if DiskTrc1[i]< 0
then Tracea[i]:= 0
else Tracea[i]:= DiskTrc1[i];
if DiskTrc2[i]< 0
then Tracec[i]:= 0
else Tracec[i]:= DiskTrc2[i];
etc...
end;
end;
procedure TScObj.Unpack(VAR DiskTrc: TDiskTrc);
var i: integer;
Prev: Integer;
Recover: Integer;
begin
Prev:= 0;
for i:= 1 to H.NrOfSamples do
begin
Recover := DiskTrc[i] + Prev;
if (Recover> 32767) OR (Recover< -32768)
then Recover:= 0;
DiskTrc[i]:= Recover;
Prev:= DiskTrc[i];
end;
Prev:= 0;
for i:= 1 to H.NrOfSamples do
begin
Recover := DiskTrc[i] + Prev;
if (Recover> 32767) OR (Recover< -32768)
then Recover:= 0;
DiskTrc[i]:= Recover;
Prev:= DiskTrc[i];
end;
end;
는 임시 로더 객체 (SC)의 정보는 다음과 같이 좀 더 "확실한"개체로 옮겨진된다
TSam = class
etc...
for i:= 1 to NrOfSamples DO
begin
CMX[i].Tracea:= SC.Tracea[i];
CMX[i].Tracec:= SC.Tracec[i];
etc...
end;
편집 2 : 이 버그는 특정 (2 개) 파일 세트를 열거 나로드하려고 시도 할 때만 나타납니다. 다른 모든 파일의 경우 버그가 표시되지 않습니다.
TDiskTrc의 선언은 무엇입니까? 요소 크기가 충분히 크거나 (적어도 2) 아니면 각 요소에 너무 많은 (2) 바이트를 읽으려고 메모리를 덮어 쓰고 있습니까? 또한, 스왑 및 언팩은 무엇을합니까? –
안녕하세요. TOndrej. 포장을 풀기 위해 내 게시물을 업데이트했습니다. TDiskTrc는이 두 바이트를 저장할 수 있습니다. 스왑은 Delphi.system에서 정의됩니다. – Ampere
BTW, 이전 질문과 비자에 대한 링크를 추가하는 것이 좋습니다. – Alex