AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Funktionsweise von SetLength

Ein Thema von stb2050 · begonnen am 10. Aug 2011 · letzter Beitrag vom 11. Aug 2011
Antwort Antwort
Seite 1 von 2  1 2      
stb2050

Registriert seit: 3. Aug 2011
4 Beiträge
 
#1

Funktionsweise von SetLength

  Alt 10. Aug 2011, 21:17
Delphi-Version: 5
Hallo Delphi-Gemeinde,

ich versuche momentan, einen Delphi-Code in PHP umzuschreiben, dabei bin ich auf ein Problem gestoßen. Die Funktion SetLength liefert ein uns unverständliches Ergebnis zurück.

Code:
var
  test: string;

begin
    test := '';
    Writeln(test);
    SetLength(test, 3);
    Writeln (test);
    exit;
end.
Das Ergebnis des SetLenght von '' (also von nichts) ist 2NULC (in der CMD-Ausgabe wird nur 2 angezeigt), das NUL ist das ASCI-Zeichen NUL.

Kann das jemand erklären?

Vielen Dank.

Liebe Grüße,
Steffen
  Mit Zitat antworten Zitat
Klaus01

Registriert seit: 30. Nov 2005
Ort: München
5.771 Beiträge
 
Delphi 10.4 Sydney
 
#2

AW: Funktionsweise von SetLength

  Alt 10. Aug 2011, 21:29
Guten Abend,

die vergößerst das "Array"/den String
füllst ihn aber nicht mit Daten.
Dann kann da auch irgendetwas drin stehen.

Was bringt denn WriteLn(length(test)) für ein Ergebnis.

Grüße
Klaus
Klaus
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.219 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#3

AW: Funktionsweise von SetLength

  Alt 10. Aug 2011, 21:30
Naja SetLength reserviert Speicher für den String. In dem Fall für 3 Zeichen (= Bytes, wenn AnsiString). Die 3 Bytes sind nicht initialisiert, weshalb dann im String prinzipiell ALLES stehen kann. Es ist reiner Zufall was danach in test steht.
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
stb2050

Registriert seit: 3. Aug 2011
4 Beiträge
 
#4

AW: Funktionsweise von SetLength

  Alt 10. Aug 2011, 21:43
In der Tat, an einem anderen PC wird etwas anderes, als 2 NUL C zurückgegeben.

Das Ergebnis von WriteLn(length(test)) ist übrigens 0.

Ich versuche mal, den Zusammenhang zu erläutern. Ich versuche, die Delphi-Verschlüssung von http://www.swissdelphicenter.ch/de/showcode.php?id=1243 in PHP zu übersetzen. Das hat an fast allen Stellen schon geklappt, doch an folgender Stelle hänge ich:

Code:
I := Map[S[1]] + (Map[S[2]] shl 6) + (Map[S[3]] shl 12) + (Map[S[4]] shl 18);
writeln(I);
SetLength(Result, 3);
writeln(Result);
Move(I, Result[1], Length(Result));
writeln(Result);
Die Ausgabe ist (beim ersten Durchlauf)
9491535
2NULC


Beim zweiten Durchlauf:
4414743
oNULw
ETB]C

Wie kann man das erklären? An anderen PCs sind Zeilen 1 und 3 der Ausgabe gleich, nur Zeile 2 unterscheidet sich.

Liebe Grüße,
Steffen
  Mit Zitat antworten Zitat
Delphi-Laie

Registriert seit: 25. Nov 2005
1.474 Beiträge
 
Delphi 10.1 Berlin Starter
 
#5

AW: Funktionsweise von SetLength

  Alt 10. Aug 2011, 22:13
Ich benötigte die Setlength-Prozedur für Strings noch nie. Welchen Sinn soll das haben, an der Stringlänge explizit "herumzumachen", wenn/zumal/weil die Stringlänge doch automatisch bei Stringadditionen angepaßt wird?

In der Delphi(3.0)-Hilfe steht dazu folgends:

"Bei einem langen String weist SetLength den mit S angegebenen String mit der neuen Länge erneut zu. Dabei bleiben die im String gespeicherten Zeichen erhalten, jedoch ist der Inhalt des neu zugewiesenen Speicherbereichs nicht definiert."

Also, die ominösen "2NULC" sind demnach wohl "Speicherleichen" und wurden von einem anderen Programm vorher benutzt oder sind (reiner?!) Zufall.
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#6

AW: Funktionsweise von SetLength

  Alt 10. Aug 2011, 22:18
Also, dass Zeilen 1 und 3 jemals gleich sind bezweifle ich sehr stark.

Der Rest wurde schon erklärt. Nach setlength die Stringvariable auszugeben - die vorher leer war - ist ziemlich sinnlos. Schlage ein Buch deiner Wahl auf irgendeiner Seite auf und tippe irgendwo in den Text und schau dir die drei Buchstaben links neben deinem Finger an. Die haben dann etwa genau denselben Informationsgehalt wie deine zweite Zeile.


Also:
I := Map[S[1]] + (Map[S[2]] shl 6) + (Map[S[3]] shl 12) + (Map[S[4]] shl 18); Hier werden 4 Zahlenwerte addiert. Map[s[1]] ist erstmal das erste Zeichen in S, damit gfehst du an die entsprechende Stelle im Array Map (bei "A" z.B. an Stelle 65+1) und schaust welche Zahl dass ist. bei den anderen Summanden ist das etwas ähnlich, nur dass da die Bits noch etwas nach links verschoben werden (du kannst auch mit 2^n multiplizieren; wobei n hier 6, 12 oder 18 ist)

Jetzt hast du im Speicher eine Zahl stehen, genauer ein Integer bestehend aus eigentlich 4 Bytes, also 32bit. Aber wenn du die obige Rechnung genauer ansiehst, siehst du, dass du nur 3 Bytes besetzt hast, weil deine Zahl nicht größer werden kann. Und diese ausgerechneten 3 Bytes siehst du jetzt einfach als 3 Zeichen an.
Das wars.
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von rollstuhlfahrer
rollstuhlfahrer

Registriert seit: 1. Aug 2007
Ort: Ludwigshafen am Rhein
1.529 Beiträge
 
Delphi 7 Professional
 
#7

AW: Funktionsweise von SetLength

  Alt 10. Aug 2011, 22:25
Ich möchte an dieser Stelle mal sehr vom Thema abweichen:

Von der Sicherheit her, würde ich empfehlen, was vorhandenes zu nehmen (ala AES, Blowfish, Twofish, ...). Für diese Algorithmen gibt es in fast allen Sprachen (Delphi, C, PHP, auch JS) entsprechende Implementierungen, die zueinander kompatibel sind.

Noch was zu PHP: Arrays haben dort keine feste Länge, weshalb es auch keine Funktion wie SetLength() gibt.

Bernhard
Bernhard
Iliacos intra muros peccatur et extra!
  Mit Zitat antworten Zitat
stb2050

Registriert seit: 3. Aug 2011
4 Beiträge
 
#8

AW: Funktionsweise von SetLength

  Alt 10. Aug 2011, 22:57
@rollstuhlfahrer: Grundsätzlich hast Du Recht - leider ist die Delphi-Verschlüsselung in dem Programm, dessen Daten ich mit PHP entschlüsseln musst, fest enthalten und ich kann nicht davon abweichen.

@sirius: Soweit habe ich das verstanden, ich glaube das mit den Zahlen ist auch nicht das Problem.

Ich vermute, dass mein Unverständnis an der Delphi-Funktion move begründet ist.

Code:
var
  dest : AnsiString;
  source: LongInt;

begin

 source := 9491535;
 dest  :='';

 SetLength(dest, 3);
 Move(source, dest[1], 3);

 Writeln(source);
 Writeln(dest);

end.
Kann mir jemand erklären, warum dest als Ergebnis (drittes Zeichen: CR) ist. Eigentlich sollten ja nur die ersten 3 Zeichen von source in dest kopiert werden. Findet hier irgendwo eine Umkonvertierung statt?

Liebe Grüße,
Steffen
  Mit Zitat antworten Zitat
Benutzerbild von sirius
sirius

Registriert seit: 3. Jan 2007
Ort: Dresden
3.443 Beiträge
 
Delphi 7 Enterprise
 
#9

AW: Funktionsweise von SetLength

  Alt 10. Aug 2011, 23:15
Dein Zahl "9491535" schreiben wir mal kurz um in Hex:
00 90 D4 4F
oder als Little Endian
4F D4 90 00

Das da oben steht also im Speicher. mit mov werden die ersten 3 Bytes (also: 4F D4 90) in den String kopiert. Wenn du das jetzt ausgibst, werden die Bytes als ZEichen interpretiert, und jetzt schau mal in eine handelsübliche ASCII/ANSI-Tabelle mit Cp1252.
4F = O
D4 = Ô
90 = É
Dieser Beitrag ist für Jugendliche unter 18 Jahren nicht geeignet.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#10

AW: Funktionsweise von SetLength

  Alt 11. Aug 2011, 00:36
Tja, in PHP werden Strings eben initialisiert.
Das geschieht in Delphi nicht, aus performancegründen, denn wenn man SetLength verwendet, sollte man danach auch die reservierten Dinge initialisieren, bzw. gleich mit den gewünschten Werten füllen und bei Letzerem wäre eine vorherige automatische Initialisierung nur unnötiger Overhead.

Und wenn jemand es eben nichts befüllt/initialisiert, dann soll man sich auch nicht wundern, wenn etwas unerwartetes darin erscheint.
Genauso wie bei nichtinitialisierten lokalen Variablen.


Wenn man das SetLenght hoch genug wählt, dann kann ich euch garantieren, was sich in dem String befinden wird.

Bei kurzen Strings und wird ein Speicherblock vom Delphi-Memory-Manager verwendet und jenachdem ob und für was dieser Speicherblock vorher verwendet wurde, befindet sich doch auch schon "irgendwas" drin.

Wird der String aber größer, als der größte verwaltete Block des MM, wird direkt bei Windows ein Speicherbereich extra für diesen String bestellt und da Windows sowas immer mit 0 initialisiert, wird der String auch auch nur vielen #0 bestehen.


PS: Delphi-Referenz durchsuchenDupeString und Delphi-Referenz durchsuchenStringOfChar
$2B or not $2B

Geändert von himitsu (11. Aug 2011 um 00:39 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:14 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