![]() |
Delphi-Version: 5
BoolToStr wirft Access Violation
Hallo Community,
ich bin mal wieder einem Mysterium auf der Spur: die von mir schon mehrfach verwendete Methode BoolToStr produziert in meinem Projekt eine Zugriffsverletzung, wenn der boolean-Wert true ist. Bei false nicht! Ich habe ein neues Projekt erstellt um das zu testen und dort geht es, obwohl es die gleiche Methode ist, die gleiche Delphi-Version, eben alles gleich. Ich benutze die Methode BoolToStr ohne den optionalen Parameter, packe also nur meinen boolean rein a la
Delphi-Quellcode:
meine delphi-version ist übrigens xe2, nicht 5
TMyArray = record
i : integer; b : boolean; s : String; function GetSelfAsString : string; //String-Darstellung des Objekts end; function TMyArray.GetSelfAsString: string; begin result := 'i=' + inttostr(i) + delimiter2 + 'b=' + booltostr(b) + delimiter2 + 's=' + s; end; |
AW: BoolToStr wirft Access Violation
Was für einen Wert hat b genau? Den True ist als nicht falsch also <> 0 definiert.
In Delphi hat True normalerweise den wert 1 in C (WinAPI) aber -1 ( Komplement von 0) |
AW: BoolToStr wirft Access Violation
als integer gecastet 108, interessant, 1 sollte es sein, wie kann denn sowas sein? ^^
(ich weiß, dass der boolean nur das rechteste bit des bytes interpretiert und wenn das 1 ist, ist es true, andernfalls false. aber wie schaffe ich es, die anderen 7 bits zu befüllen? indem ich bit-shifting betreibe (shl, shr) ??? |
AW: BoolToStr wirft Access Violation
Implementiere am Besten eine eigene Funktion dafür.
Wenn 0 dann False sonst True |
AW: BoolToStr wirft Access Violation
Zitat:
Ein Array über dessen Grenzen geschrieben wurde? so als Beispiele. Zitat:
Delphi-Quellcode:
oder
integer(mybool):=12345;
Delphi-Quellcode:
type
r1 = packed record w1:word; b1:boolean; end; begin move(@irgendwo,@w1,6); end; Gruß K-H [/DELPHI] |
AW: BoolToStr wirft Access Violation
Zitat:
Delphi-Quellcode:
schreiben sollte, denn es kann passieren, dass die Bedingung zwar wahr aber nicht gleich
if Bedingung = True then
Delphi-Quellcode:
ist.
True
Beweis:
Delphi-Quellcode:
if Boolean(2) then
ShowMessage('2 ist wahr'); if Boolean(2) <> True then ShowMessage('2 ist ungleich true'); |
AW: BoolToStr wirft Access Violation
Zitat:
Delphi-Quellcode:
und falls es verständlicher sein soll
BoolToStr(b <> False)
Delphi-Quellcode:
also einfach den Boolean "neu berechnen" lassen, bzw. einen neuen Boolean zu erstellen.
BoolToStr(b <> False, True)
Aber am Besten du reparierst die Stelle, wo dieser Boolean befüllt wird, damit erst garnicht dieses böse "true" darin auftaucht. PS: Seit einer Weile besitzen Objekte eine neue Methode:
Delphi-Quellcode:
(man kann sie überschreiben und so für eigene Objekte diese Funktionalität implementieren)
function ToString: string; virtual;
Daher würde ich eher empfehlen das GetSelfAsString in ToString umzubenennen, damit du ein einheitliches System bekommst. |
AW: BoolToStr wirft Access Violation
hallo und dankeschön an alle
ich befürchte fast, in meinem fall liegt es wohl an move... ich habe dazu eine frage und würde sie hier einfach mal stellen und keinen neuen thread aufmachen: gesetz dem fall, mein record beinhaltet einen string (genauer gesagt ist es ein array of string, wobei weder die länge des arrays zur designzeit fest definiert ist, noch die der enthaltenen strings (ist nicht von mir)) und es gibt ein array of record von diesem record und es wird ein move gemacht a la
Delphi-Quellcode:
was ist das Ergebnis? Kauderwelsch oder? ^^
move(MyArrayOfMyRecord[i], MyArrayOfMyRecord[i-1], (length(MyArrayOfRecord)-i) * sizeof(MyRecord));
setlength(MyArrayOfMyRecord, length(MyArrayOfMyRecord)-1); Weil er kann ja die Größe meines Records nicht anhand des Typs bestimmen, weil weder Länge des Strings, noch Länge des StringArrays fest sind. Er könnte höchstens die Größe eines ganz bestimmten Objektes dieses Typs ermitteln, was bedeuten würde, ich müsste die Summe an Bytes, die er moven soll, selbst bestimmen aus der Summe der Größe aller zu verschiebenden Elemente anstatt die Größe des Records mit der Anzahl zu multiplizieren, richtig? Ließe sich dieses Problem umgehen, wenn man aus dem Record eine Klasse machen würde? @kinzler: ToString kenn ich doch von Java, da hat Delphi wohl abgeguckt? ;) |
AW: BoolToStr wirft Access Violation
Move mit Strings in Records gehen nicht.
Wenn Du so etwas brauchst dann in der Art: mytext: array[0..20] of AnsiChar o.ä. |
AW: BoolToStr wirft Access Violation
ok, irgendwie "ringt das eine bell" ;)
und wenn ich aus dem Record ne Klasse mache, würde es dann gehen? Das Problem bleibt ja eigentlich das gleiche, die Größe des Strings (und damit auch der Klasse) hängt davon ab, was man reinschreibt (??) |
AW: BoolToStr wirft Access Violation
Zitat:
ShortString und statische Char-Arrays gehn. Genauso wie es bei Interfaces, Variants und dynamischen Arrays auch nicht geht, bzw. nicht ohne Beachteung gewisser Dinge, bei deren automatischen Speicherwerwaltung. In der Unit System gibt es eine Abteilung "Compiler helper for initializing/finalizing variable" mit netten Funktionen. New Dispose Initialize InitializeArray InitializeRecord Finalize FinalizeArray FinalizeRecord CopyArray CopyRecord Welche Delphi intern verwendet und die man notfalls selber verwenden könnte, aber dennoch sollte man ein bissl Ahnung davon haben, wie z.B. die Speicherverwaldung und Referenzzählung arbeiten. Ansonsten: Finger weg, von direkten Speichermanipulationen. (Pointer, Move und Co.) |
AW: BoolToStr wirft Access Violation
Zitat:
Zeiger belegen immer 4 Byte, deshalb sind alle Elemente des Arrays gleich groß. Das Element[i] wird mit Move überschrieben, ohne das die Speicherverwaltung der dort referenzierten Strings etwas mitbekommt. Diese Strings werden nie mehr freigegeben. Kann man so umgehen:
Delphi-Quellcode:
Nach dem Move verweist das letzte und das vorletzte Element auf die selben Strings, diese wissen aber nichts von der zusätzlichen Referenz. Das anschließende SetLength löscht das letzte Element und verringert den Referenzzähler der Strings. Dadurch werden diese freigegeben obwohl ja noch ein Element darauf verweist.
Finalize(MyArrayOfMyRecord[i]);
move(MyArrayOfMyRecord[i], MyArrayOfMyRecord[i - 1], (Length(MyArrayOfRecord) - i) * Sizeof(MyRecord)); Kann man so umgehen:
Delphi-Quellcode:
FillChar(MyArrayOfMyRecord[Length(MyArrayOfRecord) - 1], Sizeof(MyRecord), #0);
SetLength(MyArrayOfMyRecord, Length(MyArrayOfRecord) - 1); |
AW: BoolToStr wirft Access Violation
Zusammenfassend lässt sich also sagen:
Delphi-Quellcode:
wird zu
move(MyArrayOfMyRecord[i], MyArrayOfMyRecord[i-1], (length(MyArrayOfRecord)-i) * sizeof(MyRecord));
setlength(MyArrayOfMyRecord, length(MyArrayOfMyRecord)-1);
Delphi-Quellcode:
Finalize(MyArrayOfMyRecord[i]);
move(MyArrayOfMyRecord[i], MyArrayOfMyRecord[i-1], (length(MyArrayOfRecord)-i) * sizeof(MyRecord)); FillChar(MyArrayOfMyRecord[Length(MyArrayOfRecord) - 1], Sizeof(MyRecord), #0); setlength(MyArrayOfMyRecord, length(MyArrayOfMyRecord)-1); |
Alle Zeitangaben in WEZ +1. Es ist jetzt 06:29 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz