Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Änderung einer Variablen bewirkt Änderung des Feldinhalts (https://www.delphipraxis.net/174865-aenderung-einer-variablen-bewirkt-aenderung-des-feldinhalts.html)

roadrunner-S51 15. Mai 2013 08:21

Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
Hallo,

bei einem Delphi-Programm ist mir neulich ein merkwürdiger Fehler aufgefallen. Wenn ich den Inhalt einer String-Variablen ändere, ändert sich in einem dynamischen Array, was mit dieser Variablen nicht zu tun hat, der Inhalt eines Elements. Dies führt im weiteren Ablauf zu Schreibfehlern u.a..

Ist jemandem schonmal das Problem so oder ähnlich aufgefallen? Vielen Dank schonmal für eure Antworten!

baumina 15. Mai 2013 08:41

AW: Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
Hört sich nach nicht sauberer Speicherverwaltung an ... getmem, freemem, irgendwie sowas.

roadrunner-S51 15. Mai 2013 08:55

AW: Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
Das wäre eine Idee.
Ich habe mittlerweile irgendwie das Gefühl, das der Speicher, der dem Programm zugewiesen wird nicht ausreicht. Gibt es da Grenzen?
Das Feld in dem die unbeabsichtigten Änderungen auftreten ist recht groß..., es dient als Zwischenspeicher für den Inhalt einer Textdatei. Dazu kommen noch ein paar kleinere Felder für Zwischenergebnisse der Suchen innerhalb des großen Feldes.

baumina 15. Mai 2013 09:04

AW: Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
In der Delphi-Hilfe zu Stringtypen steht:

Zitat:

String-Typen

Typ Maximale Länge Erforderlicher Speicherplatz Verwendungszweck
ShortString
255 Zeichen
2 bis 256 Byte
Abwärtskompatibilität

AnsiString
~2^31 Zeichen
4 Byte bis 2 GB
8-Bit-Zeichen (ANSI), DBCS ANSI, MBCS ANSI, Unicode-Zeichen usw.

UnicodeString
~2^30 Zeichen
4 Byte bis 2 GB
Unicode-Zeichen, 8-Bit-Zeichen (ANSI), Mehrbenutzer-Server und mehrsprachige Anwendungen

WideString
~2^30 Zeichen
4 Byte bis 2 GB
Unicode-Zeichen, Mehrbenutzer-Server und mehrsprachige Anwendungen. UnicodeString wird im Allgemeinen bevorzugt, außer für COM-Anwendungen.

roadrunner-S51 15. Mai 2013 09:12

AW: Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
Ich habe mich etwas verwirrend ausgedrückt. Mit Strings arbeitet das Programm kaum. Und die entsprechenden Längen werden immer eingehalten.
Die Textdatei ist eine csv-Datei, deren Inhalt beim Einlesen in ein Feld aus Records einsortiert wird. In dem Record kommen verschiedene Datentypen vor. Besagtes Feld besitzt 1200 Elemente. Der Fehler tritt immer bei einem Integerwert in Element 156 auf.

baumina 15. Mai 2013 09:24

AW: Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
Kannst du die relevanten Codeschnipsel posten, vielleicht fällt mir ja was auf, denn wenn Du an irgendeine Speichergrenze stoßen solltest, müsste das eher einen "out of memory"-Fehler verursachen und keine falschen Inhalte liefern.

roadrunner-S51 15. Mai 2013 09:27

AW: Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
Also der Fehler tritt an der folgenden Stelle auf:
Delphi-Quellcode:
for i := 0 to Zaehlung - 1 do
  begin
    AusFeld[i].iSchrank := FeldPlatz[i].SchrankNr;
    AusFeld[i].iAusschub := FeldPlatz[i].AusschubNr;
    AusFeld[i].iFach := FeldPlatz[i].FachNr;
    AusFeld[i].iTuete := FeldPlatz[i].PackNr;
    AusFeld[i].iStueckTuete := FeldPlatz[i].Stueck;
    AusFeld[i].Datum := FeldPlatz[i].Datum;

    // In diesem Abschnitt tritt der Fehler auf  14.05.2013
    if (AusFeld[i].iFach >= 0) and (AusFeld[i].iFach < 10) then
      sHelp1 := '000' + IntToStr(AusFeld[i].iFach);
    if (AusFeld[i].iFach > 9) and (AusFeld[i].iFach < 100) then
      sHelp1 := '00' + IntToStr(AusFeld[i].iFach);
    if (AusFeld[i].iFach > 99) and (AusFeld[i].iFach < 1000) then
      sHelp1 := '0' + IntToStr(AusFeld[i].iFach);
    if AusFeld[i].iFach > 999 then
      sHelp1 := IntToStr(AusFeld[i].iFach);

    if (AusFeld[i].iTuete >= 0) and (AusFeld[i].iTuete < 10) then
      sHelp2 := '0000' + IntToStr(AusFeld[i].iTuete);
    if (AusFeld[i].iTuete > 9) and (AusFeld[i].iTuete < 100) then
      sHelp2 := '000' + IntToStr(AusFeld[i].iTuete);
    if (AusFeld[i].iTuete > 99) and (AusFeld[i].iTuete < 1000) then
      sHelp2 := '00' + IntToStr(AusFeld[i].iTuete);
    if AusFeld[i].iTuete > 9999 then
      sHelp2 := IntToStr(AusFeld[i].iTuete);
    AusFeld[i].Barcode := sHelp1 + sHelp2;
  end;
Dabei ist "Zählung" die Größe des Feldes "AusFeld", mit welchem hier gearbeitet wird. Die Strings sind lokale Variablen. Das große Feld, welches ich in einem vorherigen Post erwähnte, Name "Speicher", wird hier nicht verwendet, aber dennoch verändert.

Der schöne Günther 15. Mai 2013 09:29

AW: Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hast du einmal Bereichsüberprüfung zur Laufzeit eingeschaltet (ist zumindest in meinem RAD Studio XE2 in der Debug-Konfiguration komischerweise standardmäßig aus)? Vielleicht geht ja da etwas über den Index hinaus und verändert Daten in Strukturen, die zufälligerweise im Speicher direkt daneben liegen...

DeddyH 15. Mai 2013 09:33

AW: Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
Ändert sich hiermit etwas?
Delphi-Quellcode:
for i := Low(AusFeld) to High(AusFeld) do

baumina 15. Mai 2013 09:42

AW: Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
Interessant wäre noch der Abschnitt, indem Du die Größe des ?Array of Record? zuweist, setlength oder wie machst du das?

nahpets 15. Mai 2013 09:47

AW: Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
Wie ist
Delphi-Quellcode:
AusFeld[i].Barcode := sHelp1 + sHelp2;
definiert?
Da Du ungarische Notation benutzt (finde ich klasse, hilft beim Lesen und Verstehen von fremden Quelltexten kolossal), gehe ich bei sHelp1 und sHelp2 von String aus.
Aber was ist Barcode? Kann es sein, dass zufällig bei Feld 156 der Inhalt von sHelp1 + sHelp2 größer wird, als das, was in Barcode hineinpasst? Es könnte in dem Fall passieren, dass im Speicher quasi über das Ende von Barcode hinausgeschrieben wird und das kann dann irgendwo im Speicher sein. Bitte prüfen (testweise) zur Laufzeit nach, ob sHelp1 + sHelp2 in Barcode hineinpassen, wenn nicht, wirf 'ne Exception oder mache irgendeine andere Fehlerbehandlung...

Sollte Barcode ein ShortString sein, dann reichen 256 Byte in sHelp1 + sHelp2 aus, um das Problem zu verursachen. Bei anderen Definitionen von Barcode als String fester Länge o. ä. müssen sHelp1 + sHelp2 in der gemeinsamen Länge zwingend <= der Länge von Barcode sein. Andernfalls kann der von Dir genannte Effekt auftreten.

roadrunner-S51 15. Mai 2013 09:50

AW: Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
Liste der Anhänge anzeigen (Anzahl: 1)
@ Der schöne Günther: Habe die Bereichsprüfung eingeschalten. Bringt keine Meldungen oder Fehler.

@ DeddyH: Da ändert sich leider auch nichts. Habe mal einen Screenshot des Feldinhaltes an der entsprechenden Stelle angefügt. Dort wo die kryptischen Zeichen und Steuerzeichen sind, sollte eigenlich stehen '0'.

baumina 15. Mai 2013 09:53

AW: Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
Ein vorheriges FillChar auf das Array[i] könnte auch schon helfen.

p80286 15. Mai 2013 09:54

AW: Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
Und den running Gag gleich hinterher, "Was für Char/String verwendest Du?"
Zeig doch mal Deine Type und Var Deklarationen.

Gruß
K-H

roadrunner-S51 15. Mai 2013 09:55

AW: Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
@ nahpets: Also alle drei Variablen, sHelp1, sHelp2 und AusFeld.Barcode sind als string deklariert. Damit habe ich die volle Länge eines Strings zur Verfügeng, wobei ich das eigentlich garnicht brauche... Ich werde mal versuchen die Strings zu begrenzen. Warum soll ich mehr Platz verwenden als nötig?

Der String-Typ müsste entsprechend meiner Version AnsiString sein.
Deklaration:
sHelp1 : String;
sHelp2 : String;

nahpets 15. Mai 2013 09:58

AW: Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
Aus diesem Block solltest Du eigentlich
Zitat:

Zitat von roadrunner-S51 (Beitrag 1215379)
Delphi-Quellcode:
    if (AusFeld[i].iFach >= 0) and (AusFeld[i].iFach < 10) then
      sHelp1 := '000' + IntToStr(AusFeld[i].iFach);
    if (AusFeld[i].iFach > 9) and (AusFeld[i].iFach < 100) then
      sHelp1 := '00' + IntToStr(AusFeld[i].iFach);
    if (AusFeld[i].iFach > 99) and (AusFeld[i].iFach < 1000) then
      sHelp1 := '0' + IntToStr(AusFeld[i].iFach);
    if AusFeld[i].iFach > 999 then
      sHelp1 := IntToStr(AusFeld[i].iFach);

    if (AusFeld[i].iTuete >= 0) and (AusFeld[i].iTuete < 10) then
      sHelp2 := '0000' + IntToStr(AusFeld[i].iTuete);
    if (AusFeld[i].iTuete > 9) and (AusFeld[i].iTuete < 100) then
      sHelp2 := '000' + IntToStr(AusFeld[i].iTuete);
    if (AusFeld[i].iTuete > 99) and (AusFeld[i].iTuete < 1000) then
      sHelp2 := '00' + IntToStr(AusFeld[i].iTuete);
    if AusFeld[i].iTuete > 9999 then
      sHelp2 := IntToStr(AusFeld[i].iTuete);
    AusFeld[i].Barcode := sHelp1 + sHelp2;

Delphi-Quellcode:
AusFeld[i].Barcode := Format('%0.5d%0.5d',[AusFeld[i].iFach,AusFeld[i].iTuete]);
machen können.
Ein String der Länge 10 sollte damit ausreichen.

Mit Strings nicht fester Länge habe ich in Arrays schon häufiger Schwierigkeiten gehabt. Das funktioniert nicht immer sauber, da im Array fester Größe ja dann letztlich irgendwo ein Feld ist, dessen Größe nicht fest ist.

roadrunner-S51 15. Mai 2013 10:14

AW: Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
So, habe das mal schnell ausprobiert. An besagter Stelle 156 ist das Problem nun weg, dafür tritt es in Element 152 auf. Ich werde nun erstmal die Strings auf die minimal erforderliche Länge kürzen.

roadrunner-S51 15. Mai 2013 10:21

AW: Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
So, ich habe nun alle Strings die ich verwende auf eine definierte Anzahl beschränkt. Damit ist das Problem behoben.

Vielen Dank an alle für die hilfreichen Tipps!

nahpets 15. Mai 2013 10:25

AW: Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
Zitat:

Zitat von roadrunner-S51 (Beitrag 1215396)
So, habe das mal schnell ausprobiert. An besagter Stelle 156 ist das Problem nun weg, dafür tritt es in Element 152 auf. Ich werde nun erstmal die Strings auf die minimal erforderliche Länge kürzen.

Jaja, dass kenne ich doch irgendwo her, geänderte Daten, geänderte Fehlerposition. Im Quelltext was geändert, Fehler ein bisserl früher oder später... Da sucht man sich 'nen Wolf.

Eventuell könntest Du den String für den Barcode ja auch erst dann aus den beiden Integervariablen per Format zusammenbauen, wenn Du ihn tatsächlich benötigst. Strenggenommen hast Du hier im Array ja eine Redundanz, die nur Speicherplatz belegt.

Will meinen:

Dort, wo Du (in welcher Form auch immer) lesend auf
Delphi-Quellcode:
AusFeld[i].Barcode
zugreifst, könntest Du ja auch das
Delphi-Quellcode:
Format('%0.5d%0.5d',[AusFeld[i].iFach,AusFeld[i].iTuete])
verwenden. Spart Dir im Array den String, egal wie Du ihn auch definieren magst.

roadrunner-S51 15. Mai 2013 10:28

AW: Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
@ nahpets: Ist keine schlechte Idee. Allerdings brauch ich den Barcode an mehrenen Stellen und den jedesmal zu basteln birgt die Gefahr ihn dann irgendwo doch zu vergessen und dann ist wieder Fehlersuche angesagt.

nahpets 15. Mai 2013 10:32

AW: Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
Dann ist speichern sinnvoller.

Morphie 15. Mai 2013 10:35

AW: Änderung einer Variablen bewirkt Änderung des Feldinhalts
 
Oder das Record in eine Klasse umwandeln und Barcode als Property einführen (Welches sich dann aus den Properties Fach und Tuete zusammensetzt)


Alle Zeitangaben in WEZ +1. Es ist jetzt 23: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