10. december 2003 - 13:48Der er
3 kommentarer og 1 løsning
GetMem - FreeMem
Jeg er løbet ind i et lille problem med hensyn til alloc og dealloc af hukommelse. Her er et eks:
Funktion til at læse en stump tekst i en stor tekstfil. På forhånd ved jeg hvor meget jeg skal læse og hvor jeg skal starte. -------------------------------------------------------- Function ReadRecord(Rec: PFixRecord; Stream: TFileStream): String; var Buffer: Pchar;
begin Buffer := NIL; try try Stream.Position := Rec^.StartLocation; GetMem(Buffer, Rec^.EndLocation - Rec^.StartLocation); Stream.ReadBuffer(Buffer^, Rec^.EndLocation - Rec^.StartLocation); Result := StrPas(Buffer); finally if Assigned(Buffer) then FreeMem(Buffer); end;
except on E: Exception do Raise Exception.create('Error in readrecord: ' + Rec^.Identification + ' : ' + E.message); end; end; --------------------------------------------------------
Ovenstående funktion kaldes i en lykke, således at jeg læser flere blokke efter hinanden.
Dette virker ok MEN: I enkelte tilfælde indeholder bufferen noget tekst fra forgående læsning efter mit kald til GetMem(). Når jeg så læser med TFileStream.ReadBuffer bliver bufferen fyldt med den korrekt tekst fra filen efterfuldt af det der står i bufferen i forvejen???
I lang tid har samarbejdsbranchen fokuseret på at forbedre enhedsfunktioner – bedre kameraer, klarere lyd og smartere software. Men den virkelige forvandling handler ikke om funktioner.
Jeg har forsøgt.... Jeg tror der er noget helt galt med min kode.
Jeg har dog fået det til at fungere med nedestående funktion: ------------------------------------------------------------------------- Function TFixFileControl.ReadRecord(Rec: PFixRecord; Stream: TFileStream; RecordBuf: TStringList): Boolean; var RecStream: TMemoryStream;
begin Buffer := NIL; try try RecStream := TMemoryStream.Create(); Stream.Seek(Rec^.StartLocation, soFromBeginning); RecStream.CopyFrom(Stream, Rec^.EndLocation - Rec^.StartLocation); RecStream.Seek(0, soFromBeginning); RecordBuf.Clear; RecordBuf.LoadFromStream(RecStream); finally if Assigned(RecStream) then RecStream.Free; end;
except on E: Exception do Raise Exception.create('Error in readrecord: ' + Rec^.Identification + ' : ' + E.message); end; end; -------------------------------------------------------------------------
Mht. dit første eksempel så mangler du at allokere een byte ekstra og skrive en #0 i den, så strpas ved hvor strengen stopper; Strpas læser jo en pchar som skal termineres.
Vil i øvrigt anbefale at smække en fillchar ind efter allokeringen. Jeg aner ikke hvor mange clock cycles sådan en kommando kommer til at koste, men det er en god praksis at nulstille alt man allokerer - lært af nød...
Det er rigtigt..... Det er sikkert derfor at bufferen blev større i nogle tilfælde. Jeg prøver det senere...tak for hjælpen.
Mit andet eksempel har vist sig at være lidt hutigere til formålet, og hvis jeg derudover skal kalde fillchar, så tror jeg at jeg holder mig til denne løsning.
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.