AW: Move und FillChar bei strings.
Delphi-Quellcode:
Da kann man doch auch gleich Move(Source, Dest, Count) schreiben, oder?
function StrMove(Dest: PChar; const Source: PChar; Count: Cardinal): PChar;
begin Result := Dest; Move(Source^, Dest^, Count); end; My Problem is, ich wäß ned was (hier) als Count anzusetzen is? :oops: |
AW: Move und FillChar bei strings.
Natürlich so, wie man es von C++ und Co. auch kennt.
Also das CharCount. Drum sieht das seit Delphi 2009 in etwa so aus, seitdem das PChar kein PAnsiChar mehr ist. :zwinker:
Delphi-Quellcode:
{$IFNDEF NEXTGEN}
function StrMove(Dest: PAnsiChar; const Source: PAnsiChar; Count: Cardinal): PAnsiChar; begin Result := Dest; Move(Source^, Dest^, Count * SizeOf(AnsiChar)); end; {$ENDIF !NEXTGEN} function StrMove(Dest: PWideChar; const Source: PWideChar; Count: Cardinal): PWideChar; begin Result := Dest; Move(Source^, Dest^, Count * SizeOf(WideChar)); end; |
AW: Move und FillChar bei strings.
Ok. Thanx. Dann kann man das aber so nicht machen (Integerüberlauf). Ich lass es jetzt sein. :wall:
Delphi-Quellcode:
function TMyStringList.MoveBytes(const Index: integer): integer;
var I: integer; begin Result := 0; for I := Index to FCount - 1 do Inc(Result, Length(FItems[I]) * SizeOf(Char)); end; |
AW: Move und FillChar bei strings.
Also vom Code her sieht es OK aus und sollte so auch funktionieren.
Aber wo werden da Bytes gemovet und wenn ja Welche? |
AW: Move und FillChar bei strings.
Zuletzt hatte ich es so. Geht aber nicht. Bringt sogar gelegentlich EInavlidPointer AV.
Delphi-Quellcode:
function TMyStringList.Add(const Value: string): integer;
begin Result := FCount; Insert(Result, Value); end; function TMyStringList.MoveBytes(const Index: integer): integer; var I: integer; begin Result := 0; for I := Index to FCount - 1 do Result := Result + Length(FItems[I]) * SizeOf(Char); end; procedure TMyStringList.Insert(const Index: integer; const Value: string); begin if FCount = FCapacity then Capacity := FCapacity + DeltaCapacity; if Index < FCount then begin Move(FItems[Index], FItems[Index + 1], MoveBytes(Index)); // FillChar(FItems[Index], Length(FItems[Index]) * SizeOf(Char), 0); Finalize(FItems[Index]); end; FItems[Index] := Value; Inc(FCount); end; procedure TMyStringList.Delete(const Index: integer); begin if Index < FCount - 1 then begin Move(FItems[Index + 1], FItems[Index], MoveBytes(Index)); // FillChar(FItems[FCount - 1], Length(FItems[FCount - 1]) * SizeOf(Char), 0); Finalize(FItems[FCount - 1]); end; FItems[FCount - 1] := ''; Dec(FCount); end; |
AW: Move und FillChar bei strings.
Für was soll das alles gut sein? Nimm TStringList und fertig!
|
AW: Move und FillChar bei strings.
Delete:
Erst Freigeben (Finalize), und zwar das, was du löschst. :warn: dann verschieben, was vor muß und das, was verschoben, aber nicht gelöscht wurde, leeren FillChar, sonst ist der Eintrag doppelt da und du hast somit die Referenzzählung zerschossen. Oder das erst den zu Löschenden zuwischenspeichern (Move in ine Tempvariable), dann verschieben und den zu löschenden an letzter Stelle einfügen (Movo) und die TempVariable natürlich, wenn man dafür den OriginalTyp verwendete, ebenfalls Nullen, da dieses sonst auch doppelt ist. Genauso beim Insert. Fazit: Erst lernen wie eigentlich die Speicherverwaltung funktioniert und dann sich an soein Projekt rantrauen. Oder du fummelst besser nicht an der Speicherverwaltung rum
Delphi-Quellcode:
Oder du nutzt fertige Codes, welche sich darum kümmern, wie z.B. die generische TList<>.
procedure ArrayDelete(var Arr: TMyArray; Index: Integer);
var i: Integer; begin for i := Index to High(Arr) - 1 do Arr[i] := Arr[i + 1]; SetLength(Arr, Length(Arr) - 1); end; |
AW: Move und FillChar bei strings.
Dann muß man den Index aber aussparen (***).
Und wie gesagt, ich laß den Blödsinn jetzt. :cyclops:
Delphi-Quellcode:
procedure TMyStringList.Delete(const Index: integer);
begin Dec(FCount); // *** if Index <= FCount then begin Finalize(FItems[Index]); if Index < FCount then begin Move(FItems[Index + 1], FItems[Index], (FCount - Index) * SizeOf(string)); FillChar(FItems[FCount], Length(FItems[FCount]) * SizeOf(Char), 0); end; end; FItems[FCount] := ''; end; |
AW: Move und FillChar bei strings.
Was ist denn FItems nun eigentlich?
Die Char-Größe muß man nur einrechnen, wenn sich die Große auf Chars bezieht. Wenn sich das nur auf einen String-Pointer und nicht auf den String-Inhalt bezieht, dann hat das dort absolut nichts zu suchen. |
AW: Move und FillChar bei strings.
FItems: array of string; (Siehe auch #1)
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:12 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz