speicher zugriffsverletztung
-
hallo zusammen.
Ich habe ein kleines Form in dem ich Werte aus einer SQL Datenbank auslese
und dann bestimmten componenten zuweise.SqlStr = "SELECT * FROM tabelle"; Form1->ADOqry->SQL->Clear(); Form1->ADOqry->SQL->Add(SqlStr); Form1->ADOqry->Open(); Form1->label1->Caption = Form1->ADOqry->FieldByName("Feldname")->AsString;Dies funktioniert soweit einwandfrei.
Über einen Button möchte ich nun dieses Form neu laden:Form1->Close(); delete Form1; TForm1 *Form1 = new TForm1(Application); Form1->Show();Wenn ich diesen Code ausführe bekomme ich eine Exeption "Speicher Zugriffsverletzung" an der Stelle:
Form1->ADOqry->Open();Das komische daran ist das diese Meldung nicht immer auftritt, manchmal erst nach dem 3 oder vierten neuladen der Form. Teilweise aber auch beim ersten mal.
Weiß jemand woran das liegen könnte?Vielen Dank für eure Hilfe
Gruß Jens
-
Durch das delete zerstörst du das Objekt "Form1" und alle darin untergebrachten Daten (inklusive deiner Datenbankabfrage 'ADOqry'). Anschließend legst du ein neues lokales Objekt namens 'Form1' an (erstaunlich, daß sich das tatsächlich compilieren lässt). Wenn danach der (globale) Zeiger 'Form1' noch auf etwas zeigt, was als gültiges Objekt angesehen werden kann, hast du viel Glück gehabt.
-
Davon abgesehen, sollte man mit CreateForm() erzeugte globale Instanzen nicht löschen.
-
Hi,
Danke für deine Antwort.
Also das läst sich einwandfrei compilieren :).
erstelle ich mit
TForm1 *Form1 = new TForm1(Application);nicht eine neue Instanz der Klasse TForm1 die sämtliche Eigenschaften und Methoden beinhaltet (also auch meine ADO Komponente)?
Oder verstehe ich hier irgend etwas falsch?Weil komischerweise funktioniert das teilweise einwandfrei. meistens erst nach mehrmaligem ausführen dieses codes kommts zum crash.
-
Ja, aber noch einmal du löscht die globale Instanz von Form1 und erzeugst eine lokale Instanz von Form1. Auf jeden Fall muß das TForm* am Anfang der Zeile weg. Ich bin mir allerdings trotzdem nicht sicher, ob das irgendwelche negativen Seiteneffekte hat. Wenn ich Formulare zu Laufzeit löschen und neu erzeugen will, nehme ich sie aus der Liste der automatisch erzeugten Formulare heraus und übernehme das Erzeugen (und Löschen) komplett selbst.
Sinnvoller wäre es allerdings, dem Formular eine Funktion zur Re-Initialisierung zu spendieren, in der Du alle Werte wieder auf die gewünschten setzt.
-
jiz0r schrieb:
Weil komischerweise funktioniert das teilweise einwandfrei. meistens erst nach mehrmaligem ausführen dieses codes kommts zum crash.
Das ist das üble an undefiniertem Verhalten (und der Zugriff auf fremde Speicherbereiche ist undefiniert).
Wenn du das Objekt per delete freigibst, merkt sich der Hepa-Managar lediglich, daß er dessen Speicher wieder verwenden darf, physisch bleibt die Bit-Struktur noch weitgehend erhalten - und mit viel "Glück" kannst du noch ohne offensichtliche Fehler darauf zugreifen. Aber irgendwann wird dem Hap-Manager der Speicher knapp und er weist diesen Block jemandem zu, der ihn per new angefordert hat - derjenige füllt ihn mit seinen eigenen Daten und beim nächsten Zugriffsversuch versuchst du, diese Daten als TForm1-Objekt zu deuten => BUMM.
-
Ok das hab ich verstanden
DankeIch denke auch das ich es über eine Re initialisirungsfunktion machen werde. ist glaube ich sicherer.