title: Allocating memory for dynamic array - The block header has been corrupted (FastMM4)
body: <p>I had a topic 1-2 weeks ago about a "The block header has been corrupted" and "Block has been modified after being freed" error.</p>
  
  <p>Somebody gave me a good tip (thanks Alexander) about setting FullDebugModeScanMemoryPoolBeforeEveryOperation to true and finally I have some indications about where is the TRUE location of the error.</p>
  
  <p>The error log points to TScObj object. I have a second object very similar to this one and when I use it the error does not appear. So, this somehow confirms that the error is in this specific object (TScObj).</p>
  
  <p>The log is like this:</p>
  
  <pre><code>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]
  </code></pre>
  
  <p>The thing is that I don't see any place in my code where I could wrongfully allocate memory.</p>
  
  <pre><code>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);    &lt;------ log shows error here. &lt;- 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);   &lt;------ log shows error here. &lt;- on FinalizeArray
  
   for i:=1 to H.NrOfSamples DO
     begin
       if DiskTrc1[i]&lt; 0
       then Tracea[i]:= 0
       else Tracea[i]:= DiskTrc1[i];
  
       if DiskTrc2[i]&lt; 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&gt;  32767) OR (Recover&lt; -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&gt;  32767) OR (Recover&lt; -32768)
       then Recover:= 0;
       DiskTrc[i]:= Recover;
       Prev:= DiskTrc[i];
     end;
  end;
  </code></pre>
  
  <p>Later during the "load from disk" procedure, the information from the temporary loader object (SC) is transfered into a more "definitive" object, like this:</p>
  
  <pre><code> TSam = class
   etc...                                                
   for i:= 1 to NrOfSamples DO
    begin
     CMX[i].Tracea:= SC.Tracea[i];
     CMX[i].Tracec:= SC.Tracec[i];
     etc...
    end;
  </code></pre>
  
  <hr>
  
  <p>Edit 2: 
  The bug appears only when I try to open/load a very specific set of (two) files. For all other files the bug doesn't show. </p>