Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Zugriffsverletzung (https://www.delphipraxis.net/189808-zugriffsverletzung.html)

schand99 25. Jul 2016 09:29

Delphi-Version: 5

Zugriffsverletzung
 
Hallo liebe Entwickler,

ich habe ein Problem mit Zugriffsverletzungen beim Aufrufen von Funktionen aus einer DLL. Die DLL "ref_calc32.dll" dient zum Berechnen von Stoffwertdaten von Kältemitteln, eine Dokumentation zu der DLL habe ich leider nicht. Nur ein Quellcodebeispiel geschrieben mit VB 6.0
Daraus konnte ich mir mit viel Probieren die Funktionen der DLL in Delphi einbinden

Zum Beispiel:
Delphi-Quellcode:
Function S_vs(ref: PAnsiChar; t, P: Double; var vs: Double): Boolean; stdcall; external DllName;
  Function S_t_d(ref: PAnsiChar; P: Double; var T_d: Double): Boolean; stdcall; external DllName;
 usw.
Zusätzlich habe ich alle DLL-Aufrufe in eine einzelne Funktion gepackt, um Probleme mit Variablen weitestgehend zu vermeiden.

Delphi-Quellcode:
Function UDllCall(FType, FName: String; TKM, XVar: Double): Double;
 Var
  Temp, res: Double;
  Refr: PAnsiChar;
  Erg: Boolean;
Begin
   //GetMem(Refr, 16);
   Temp := 273.15 + TKM;
   // Berechnen der Stoffwerte
   if FType = 'R404A' then
      Refr := PAnsiChar('r404a')
   else if FType ='R407C' then
      Refr := PAnsiChar('r407c')
   else if FType ='R134A' then
      Refr := PAnsiChar('r134a')
   else if FType ='R410A' then
      Refr := PAnsiChar('r410a')
   else if FType ='R507' then
      Refr := PAnsiChar('r507')
   else if FType ='R22' then
      Refr := PAnsiChar('r22');

   if Uppercase(FName) = 'S_TC' then
      Begin
         erg := S_tc(Refr, res);
      End;

   // usw, usw, ...

   Result := res;

End;
Allerdings bleibt ein Problem bestehen: eine Schutzverletzung. Diese tritt erst beim 62. Aufruf der Funktion auf. Und zwar nach dem 'end;' und betrifft die Freigabe von reserviertem Speicher. Ich vermute einen Zusammenhang mit der Variablen "Refr" vom Typ PAnsiChar. Ich habe auch schon versucht mit GetMem und FreeMem den für die Variable reservierten Speicherbereich zu reservieren und freizugeben. Alles ohne Erfolg.
Hat vielleicht jemand von Euch Delphiprofis einen Tipp?

schon mal vielen Dank,
Andreas

hhcm 25. Jul 2016 09:49

AW: Zugriffsverletzung
 
Und was ist, wenn das if else if konstrukt nicht zustimmt?
Dann wird ein nicht initialisierter Wert übergeben.
Denn ein abschliessendes else oder eine Initialisierung der Variable Refr findet nicht statt.

p80286 25. Jul 2016 10:37

AW: Zugriffsverletzung
 
Wenn ich mich nicht verlesen habe sollte ein simples
Delphi-Quellcode:
LowerCase
bzw. sein entsprechendes Pendant dieses
Delphi-Quellcode:
If..else if..else if
- Monstrum ersetzen können.

Und ansonsten frag mal den Debugger wo es da ein Problem gibt [F7] sollte da sehr hilfreich sein.

Gruß
K-H

baumina 25. Jul 2016 10:57

AW: Zugriffsverletzung
 
Vielleicht hilfts ja : http://www.studfiles.ru/preview/3378435/

ConnorMcLeod 25. Jul 2016 11:02

AW: Zugriffsverletzung
 
Gib mal die Parameter in eine Log-Datei aus und prüfe dort, ob das Erwartete übergeben wird.

schand99 25. Jul 2016 12:03

AW: Zugriffsverletzung
 
Schon mal Danke für die Hinweise.

Es ist sichergestellt, dass 'Refr' niemals leer ist. 'FType' enthält immer den Name des Kältemittels, das wird schon vor dem Aufrufen der Funktion sichergestellt.
Das mit dem if... else if... sieht nicht schön aus und es macht für die DLL auch keinen Unterschied ob Groß- oder Kleinbuchstaben übergeben werden. Allerdings, und das ist auch etwas was ich nicht verstehe, wenn ich der Pointer-Variablen "Refr" unter Verwendung von Refr := PAnsiChar(FType) den String zuweise, dann funktioniert die DLL nicht, gibt immer 0 zurück.

schand99 25. Jul 2016 12:22

AW: Zugriffsverletzung
 
Der Fehler wird in "function SysFreeMem(P: Pointer): Integer" aus Getmem.inc ausgelöst.

Delphi-Quellcode:
function SysFreeMem(P: Pointer): Integer;
asm
{$ifdef CPU386}
{---------------32-bit BASM SysFreeMem---------------}
  {On entry:
    eax = P}
  {Get the block header in edx}
  mov edx, [eax - 4]
  {Is it a small block in use?}
  test dl, IsFreeBlockFlag + IsMediumBlockFlag + IsLargeBlockFlag
  {Save the pointer in ecx}
  mov ecx, eax
  {Save ebx}
  push ebx
  {Get the IsMultiThread variable in bl}
  mov bl, IsMultiThread
  {Is it a small block that is in use?}
  jnz @NotSmallBlockInUse
  {Do we need to lock the block type?}
  test bl, bl
  {Get the small block type in ebx}
  mov ebx, TSmallBlockPoolHeader[edx].BlockType
in dem letzten Befehl mov ebx, TSmallBlockPool... stürzt das Programm ab. Deshalb hatte ich schon mit GetMem und FreeMem versucht, den Platz für den Pointer 'Refr' zu reservieren und manuell wieder freizugeben.
Könnte es sein, dass die 32 Bit DLL auf einem 64 Bit Sytem nicht so funktioniert wie sie soll? Als Zielplattform habe ich zwar Win32 eingestellt, aber man weiß ja nie...

Luckie 25. Jul 2016 13:45

AW: Zugriffsverletzung
 
Werden die Aufrufkonventionen der DLL Funktion beachtet? Irgendwer versucht da aufzuräumen, obwohl wohl schon alles aufgeräumt ist.

schand99 25. Jul 2016 16:14

AW: Zugriffsverletzung
 
Zitat:

Zitat von Luckie (Beitrag 1343296)
Werden die Aufrufkonventionen der DLL Funktion beachtet?

Ja, im Rahmen dessen was die verfügbaren Dokus hergeben. Also das 17 Jahre alte PDF aus Russland und der VB6-Quellcode. Habe auch schon sehr viele andere Konventionen ausprobiert. Ergebnisse aus der DLL gibt es nur dann, wenn die Konventionen aus meinem ersten Post verwendet werden.
Auf dem alten PDF ist eine Telefonnummer zu finden, die könnte möglicherweise geholfen haben. Es wird sich zeigen, ob die neuen Eigentümer der ref_calc32.dll eine aktuelle Version der DLL samt Doku rausrücken :-D

hoika 25. Jul 2016 22:08

AW: Zugriffsverletzung
 
Hallo,
also nach dem hier ist es nicht Boolean, sondern WordBool.

k.A., ob das jetzt das gleiche ist.

http://www.studfiles.ru/preview/3378442/

schand99 26. Jul 2016 06:51

AW: Zugriffsverletzung
 
Boolean und WordBool sind beide logische Variablentypen. Boolean belegt ein 1 Byte, WordBool 2. Soviel sagt die Doku von Embarcadero.
Hatte in meinem Programm schon auf WordBool umgestellt, macht keinen Unterschied. 62 DLL Aufrufe funktionieren, beim 63 gibt's den Crash :(
In einem Log-File, das nun die DLL Aufrufe samt Parametern protokolliert, ist kein Fehler erkennbar. Dafür aber dass nach 62 Aufrufen Schluss ist, die hatte ich vorher umständlich mitgezählt :roll:

bra 26. Jul 2016 08:41

AW: Zugriffsverletzung
 
Aus dem unvollständigen Quelltext wird leider nicht deutlich, ob alle Variablen auch wirklich initialisiert sind. So wie Refr sonstwas enthält, wenn der if-else-Block nicht greift.
Und res wird auch nicht initialisiert, aber ich vermute das soll ein Rückgabewert sein?

schand99 26. Jul 2016 11:00

AW: Zugriffsverletzung
 
Der if / else if block greift immer, das wird wie schon weiter oben beschrieben vor dem Aufrufen der Funktion sichergestellt. 'res' ist der Rückgabewert aus der dll.
Nun werden die dll-Aufrufe mit den übergebenen Werten und den Rückgaben in eine Log-Datei geschrieben. Alle läuft fehlerfrei bis zum 62. Aufruf einer x-beliebigen DLL-Funktion, nach 62. Aufruf wird beim Verlassen der Funktion Udllcall der Fehler wegen Schutzverletzung ausgelöst

Benedikt Magnus 26. Jul 2016 11:25

AW: Zugriffsverletzung
 
Mal anders gedacht: Wenn sich aufgrund fehlender Dokumentation der Grund für die Zugriffsverletzung nicht finden lässt, wie wäre dann ein Workaround, die DLL nach jedem 62. Aufruf neuzuladen?

p80286 26. Jul 2016 12:32

AW: Zugriffsverletzung
 
Zitat:

Zitat von schand99 (Beitrag 1343434)
Alle läuft fehlerfrei bis zum 62. Aufruf einer x-beliebigen DLL-Funktion, nach 62. Aufruf wird beim Verlassen der Funktion Udllcall der Fehler wegen Schutzverletzung ausgelöst

Das klingt so als ob da ein Pointer incrementiert würde. Nur gibt der vorhandene Sourcecode da nichts her. Die Prüfung auf Bereichsüberprüfung ist aber eingeschaltet?

Gruß
K-H

schand99 26. Jul 2016 13:04

AW: Zugriffsverletzung
 
Ich glaub ich werd welk...

Der Tipp von Benedikt Magnus, das ist DER Tipp. Dachte ich mir. Habe das Programm so umgebaut, dass die DLL für jeden Aufruf dynamisch geladen wird. Die ganze Funktion sieht nun so aus:
Delphi-Quellcode:
Function UDllCall(FType, FName: String; TKM, XVar: Double): Double;
 Type
  TFreon1Para = function(ref: PAnsiChar; var dlret: Double): Boolean; stdcall;
  TFreon2Para = function(ref: PAnsiChar; t: Double; var dlret: Double): Boolean; stdcall;
  TFreon3Para = function(ref: PAnsiChar; t, p: Double; var dlret: Double): Boolean; stdcall;
 Var
  hDLL: THandle;
  FarProc1: TFreon1Para;
  FarProc2: TFreon2Para;
  FarProc3: TFreon3Para;
  Temp, res: Double;
  Refr: PAnsiChar;
  Erg: WordBool;
  f: TextFile;
  Adw: String;
Begin
   //GetMem(Refr, 16);
   Temp := 273.15 + TKM;
   // Berechnen der Stoffwerte
   Refr := PAnsiChar('r407c');
   if FType = 'R404A' then
      Refr := PAnsiChar('r404a')
   else if FType ='R407C' then
      Refr := PAnsiChar('r407c')
   else if FType ='R134A' then
      Refr := PAnsiChar('r134a')
   else if FType ='R410A' then
      Refr := PAnsiChar('r410a')
   else if FType ='R507' then
      Refr := PAnsiChar('r507')
   else if FType ='R22' then
      Refr := PAnsiChar('r22');
   hDLL := LoadLibrary(DLLName);
   if hDLL = 0 then
      begin

      end
     else
      Begin
         if Uppercase(FName) = 'S_TC' then
            Begin
               FarProc1 := GetProcAddress(hDLL, 'S_tc');
               if Assigned(FarProc1) then
                  erg := FarProc1(refr, res)
                 else
                  res := -999999;
               //erg := S_tc(Refr, res);
            End;
         if Uppercase(FName) = 'S_PC' then
            Begin
               FarProc1 := GetProcAddress(hDLL, 'S_pc');
               if Assigned(FarProc1) then
                  erg := FarProc1(refr, res)
                 else
                  res := -999999;
               //erg := S_pc(Refr, res);
            End;
         if Uppercase(FName) = 'S_P_D' then
            Begin
               FarProc2 := GetProcAddress(hDLL, 'S_p_d');
               if Assigned(FarProc2) then
                  erg := FarProc2(refr, Temp, res)
                 else
                  res := -999999;
               //erg := S_p_d(Refr, Temp, res);
            End;
         if Uppercase(FName) = 'S_H_L' then
            Begin
               FarProc2 := GetProcAddress(hDLL, 'S_h_l');
               if Assigned(FarProc2) then
                  erg := FarProc2(refr, Temp, res)
                 else
                  res := -999999;
               //erg := S_h_l(Refr, Temp, res);
            End;
         if Uppercase(FName) = 'S_H_V' then
            Begin
               FarProc3 := GetProcAddress(hDLL, 'S_h_v');
               if Assigned(FarProc3) then
                  erg := FarProc3(refr, Temp, XVar, res)
                 else
                  res := -999999;
               //erg := S_h_v(Refr, Temp, XVar, res);
            End;
         if Uppercase(FName) = 'S_SIGMA_L' then
            Begin
               FarProc2 := GetProcAddress(hDLL, 'S_sigma_l');
               if Assigned(FarProc2) then
                  erg := FarProc2(refr, Temp, res)
                 else
                  res := -999999;
               //erg := S_sigma_l(Refr, Temp, res);
            End;
         if Uppercase(FName) = 'S_VISC_L' then
            Begin
               FarProc2 := GetProcAddress(hDLL, 'S_visc_l');
               if Assigned(FarProc2) then
                  erg := FarProc2(refr, Temp, res)
                 else
                  res := -999999;
               //erg := S_visc_l(Refr, Temp, res);
            End;
         if Uppercase(FName) = 'S_VISC_V'then
            Begin
               FarProc3 := GetProcAddress(hDLL, 'S_visc_v');
               if Assigned(FarProc3) then
                  erg := FarProc3(refr, Temp, XVar, res)
                 else
                  res := -999999;
               //erg := S_visc_v(Refr, Temp, XVar, res);
            End;
         if Uppercase(FName) = 'S_V_L' then
            Begin
               FarProc2 := GetProcAddress(hDLL, 'S_v_l');
               if Assigned(FarProc2) then
                  erg := FarProc2(refr, Temp, res)
                 else
                  res := -999999;
               //erg := S_v_l(Refr, Temp, res);
            End;
         if Uppercase(FName) = 'S_V_V' then
            Begin
               FarProc3 := GetProcAddress(hDLL, 'S_v_v');
               if Assigned(FarProc3) then
                  erg := FarProc3(refr, Temp, XVar, res)
                 else
                  res := -999999;
               //erg := S_v_v(Refr, Temp, XVar, res);
            End;
         if Uppercase(FName) = 'S_CP_L' then
            Begin
               FarProc2 := GetProcAddress(hDLL, 'S_cp_l');
               if Assigned(FarProc2) then
                  erg := FarProc2(refr, Temp, res)
                 else
                  res := -999999;
               //erg := S_cp_l(Refr, Temp, res);
            End;
         if Uppercase(FName) = 'S_LAMBDA_L' then
            Begin
               FarProc2 := GetProcAddress(hDLL, 'S_lambda_l');
               if Assigned(FarProc2) then
                  erg := FarProc2(refr, Temp, res)
                 else
                  res := -999999;
               //erg := S_lambda_l(Refr, Temp, res);
            End;
         if Uppercase(FName) = 'S_LAMBDA_V' then
            Begin
               FarProc3 := GetProcAddress(hDLL, 'S_lambda_v');
               if Assigned(FarProc3) then
                  erg := FarProc3(refr, Temp, XVar, res)
                 else
                  res := -999999;
               //erg := S_lambda_v(Refr, Temp, XVar, res);
            End;
         if Uppercase(FName) = 'S_VS' then
            Begin
               FarProc3 := GetProcAddress(hDLL, 'S_vs');
               if Assigned(FarProc3) then
                  erg := FarProc3(refr, Temp, XVar, res)
                 else
                  res := -999999;
               //erg := S_vs(Refr, Temp, XVar, res);
            End;
         if Uppercase(FName) = 'S_T_D' then
            Begin
               FarProc2 := GetProcAddress(hDLL, 'S_t_d');
               if Assigned(FarProc2) then
                  erg := FarProc2(refr, XVar, res)
                 else
                  res := -999999;
               //erg := S_t_d(Refr, XVar, res);
            End;
         if Uppercase(Fname) = 'S_CV' then
            Begin
               FarProc3 := GetProcAddress(hDLL, 'S_cv');
               if Assigned(FarProc3) then
                  erg := FarProc3(refr, Temp, XVar, res)
                 else
                  res := -999999;
               //erg := S_cv(Refr, Temp, XVar, res);
            End;
      End;
   if Erg then
      Adw := 'erg True'
     else
      Adw := 'erg False';

   AssignFile(f, Logfile);
   if FileExists(Logfile) then
      Append(f)
     else
      Rewrite(f);
   WriteLn(f, FType + ' -> ' + FName + ' -> ' + FloatToStr(TKM) + ' -> ' + FloatToStr(XVar) + ' => ' + FloatToStr(res)+ ' / ' + Adw);
   CloseFile(f);
   erg := FreeLibrary(hDLL);
   Result := res;
End;
Aber leider: nach dem 62zigsten Aufruf der Funktion ist Ende. Genau der selbe Fehler wegen Schutzverletzung. Querprüfung mit dem alten VB6-Code zeigt, dass die an die DLL übergebenen Werte weitestgehend übereinstimmen. Im VB6 gibt es aber keinerlei Probleme.

Bereichsprüfung sehe ich soeben in einem anderen Post. Ist das eine Compileroption?

bra 26. Jul 2016 13:26

AW: Zugriffsverletzung
 
Wenn bei FName was ungültiges übergeben wird, hast du wieder einen Haufen uninitialisierte Variablen ;)

p80286 26. Jul 2016 13:34

AW: Zugriffsverletzung
 
Zitat:

Zitat von schand99 (Beitrag 1343471)
Ich glaub ich werd welk...


Aber leider: nach dem 62zigsten Aufruf der Funktion ist Ende. Genau der selbe Fehler wegen Schutzverletzung.

Dann ist die DLL augenscheinlich nicht schuld.
Zitat:

Zitat von schand99 (Beitrag 1343471)
Bereichsprüfung sehe ich soeben in einem anderen Post. Ist das eine Compileroption?

Jo

Gruß
K-H

schand99 26. Jul 2016 13:39

AW: Zugriffsverletzung
 
Zitat:

Zitat von bra (Beitrag 1343477)
Wenn bei FName was ungültiges übergeben wird, hast du wieder einen Haufen uninitialisierte Variablen ;)

Stimmt theoretisch, passiert aber definitiv nicht. Da der dynamische Aufruf der dll ohnehin keine Besserung gebracht hat, werde ich wieder auf Statisch umbauen. Für die Ausführungsgeschwindigkeit (sollte ich die Sache endlich mal zum Laufen bringen) eindeutig ein Vorteil. Irgendwo ist der Wurm drin, ein paar Tage Pause oder Abstand zu dem Programm und vielleicht sehe ich dann das was ich bisher immer übersehe....:stupid:

Bambini 26. Jul 2016 15:04

AW: Zugriffsverletzung
 
Zitat:

Zitat von p80286 (Beitrag 1343480)
Zitat:

Zitat von schand99 (Beitrag 1343471)
Ich glaub ich werd welk...
Aber leider: nach dem 62zigsten Aufruf der Funktion ist Ende. Genau der selbe Fehler wegen Schutzverletzung.

Dann ist die DLL augenscheinlich nicht schuld.

Vielleicht gibt die DLL die übergebenen Variablen bereits frei. Daher raucht die Delphi SysFreeMem() Funktion beim Aufräumen der Routine.
Erzeuge doch mal die AnsiString Variable mit New(), damit Delphi diese nicht mehr aufräumen kann.
Damit entstehen zwar Delphi Memory Leaks, aber evtl. hören die AV auf.

schand99 27. Jul 2016 08:05

AW: Zugriffsverletzung
 
Rätsel gelöst, ich hatte immer die DLL in Verdacht, da Anfangs in einer Funktion am
Delphi-Quellcode:
End;
der Fehler ausgelöst wurde. Durch Umbau von mehreren Berechnungsfunktionen welche Berechnungen aus der DLL benötigten, habe ich dann entdeckt, dass die Freigabe von dynamischen Array's am Ende einer Funktion die Ursache für die Schutzverletzung war. Diese Freigabe erfolgt normalerweise automatisch am
Delphi-Quellcode:
End;
durch manuelles SetLenght(Variable, 0) konnte ich das Problem genauer einkreisen. Zwei dynamische Array's waren noch ok, ab dem dritten gibt es die Schutzverletzung. Ich verstehe zwar nicht warum das so ist, habe zur Zeit aber nicht die Geduld dem auf den Grund zu gehen. Umstellen auf statische Array's war die Lösung.

Tut mir leid dass einige von Euch über meine (falsche) Vermutung zur Fehlerquelle gegrübelt haben,

Gruß
Andreas

Neutral General 27. Jul 2016 08:09

AW: Zugriffsverletzung
 
Bin mir ziemlich sicher, dass es nicht an der Tatsache lag dass du dynamische Arrays benutzt hast.
Garantiert hast du irgendwo über die Grenzen einer deiner dyn. Arrays geschrieben (oder unter die Grenzen).

Dass es mit statischen Arrays geht ist vielleicht nur Zufall oder du hast "aus Versehen" eine Größe gewählt die deinen Fehler "verschwinden" lässt.
(Das heißt nicht, dass er weg ist!)

p80286 27. Jul 2016 10:14

AW: Zugriffsverletzung
 
Zitat:

Zitat von Neutral General (Beitrag 1343535)
Bin mir ziemlich sicher, dass es nicht an der Tatsache lag dass du dynamische Arrays benutzt hast.
Garantiert hast du irgendwo über die Grenzen einer deiner dyn. Arrays geschrieben (oder unter die Grenzen).

Dass es mit statischen Arrays geht ist vielleicht nur Zufall oder du hast "aus Versehen" eine Größe gewählt die deinen Fehler "verschwinden" lässt.
(Das heißt nicht, dass er weg ist!)

Das ist aber sehr diplomatisch.

Gruß
K-H

schand99 27. Jul 2016 12:05

AW: Zugriffsverletzung
 
Sehr diplomatisch?

Die Situation ist etwas verzwickt. Ich habe einen etwas älteren Quellcode einer VB6 Anwendung und muss den "übersetzen". VB6 ist sehr fehlertolerant, das ist nicht unbedingt hilfreich.
Eine Serie von 11(!!) dynamischen Array's wird verwendet um thermo- und physikalische Eigenschaften eines Kältemittels zu berechnen

also
Delphi-Quellcode:
Var
 Variable1, Variable2, Variable3, Variable4, Variable5: Array of Double;

Begin
...
...
  SetLength(Variable1, X)
  SetLength(Variable2, X)
  ...
  ...
  ' ein paar Schleifen...

  SetLength(Variable1, 0)
  SetLength(Variable2, 0)
  SetLength(Variable3, 0)  

End;
die Variable X ist immer kleiner gleich 20, das ist nicht groß. Es wäre allerdings möglich, dass irgend ein Wert eines Array's nicht gesetzt wird (fällt mir jetzt ein, das kann ich ggf. ausprobieren)

Neutral General 27. Jul 2016 12:13

AW: Zugriffsverletzung
 
Die Schleifen wo die Arrays gefüllt werden, wären wichtiger

schand99 27. Jul 2016 16:29

AW: Zugriffsverletzung
 
Jetzt hab ich mir mal einen kleinen Spaß gemacht:

Delphi-Quellcode:
Function WasSolldas(Irgendwas: String): Double;
  Var
  J, M: Integer;
  BogNr, xBog, xTube, beta, Hbeta, eps, Heps, MDich, ZetaBogKM, DPBog, DpDlzphM: array of Double;
begin
   M := 8;
   SetLength(BogNr, M);
   SetLength(xBog, M);
   SetLength(xTube, M);
   SetLength(beta, M);
   SetLength(Hbeta, M);
   SetLength(eps, M);
   SetLength(Heps, M);
   SetLength(MDich, M);
   SetLength(ZetaBogKM, M);
   SetLength(DPBog, M);
   SetLength(DpDlzphM, M);

   for J := 0 to M do
      begin
         BogNr[J] := 0;
         xBog[J] := 0;
         xTube[J] := 0;
         beta[J] := 0;
         Hbeta[J] := 0;
         eps[J] := 0;
         Heps[J] := 0;
         MDich[J] := 0;
         ZetaBogKM[J] := 0;
         DpBog[J] := 0;
         DpDlzphM[J] := 0;
      end;

   SetLength(BogNr, 0);
   SetLength(xBog, 0);
   SetLength(xTube, 0);
   SetLength(beta, 0);
   SetLength(Hbeta, 0);
   SetLength(eps, 0);
   SetLength(Heps, 0);
   SetLength(MDich, 0);
   SetLength(ZetaBogKM, 0);
   SetLength(DPBog, 0);
   SetLength(DpDlzphM, 0);
   Result := 0;
End;
Resultat: das Programm steigt bei SetLenght(xBog, 0); mit Schutzverletzung aus.

Delphi 10.1 Berlin

Was mach ich da falsch?

Neutral General 27. Jul 2016 16:30

AW: Zugriffsverletzung
 
Jupp, genau das.
Ein M-Langes Array hat Indices von 0 bis M-1.
Das hast du bei deiner for-Schleife nicht beachtet, deswegen schreibst du in unreservierten Speicher und das kracht früher oder später.

schand99 27. Jul 2016 17:56

AW: Zugriffsverletzung
 
Oh Mann, du hast recht. Wie peinlich.
Den Thread bitte schließen.
Oder Löschen, das wär für mich noch besser :oops:

p80286 27. Jul 2016 18:01

AW: Zugriffsverletzung
 
Zitat:

Zitat von Neutral General (Beitrag 1343599)
Jupp, genau das.
Ein M-Langes Array hat Indices von 0 bis M-1.
Das hast du bei deiner for-Schleife nicht beachtet, deswegen schreibst du in unreservierten Speicher und das kracht früher oder später.

:thumb:
Zitat:

Zitat von schand99 (Beitrag 1343619)
Oh Mann, du hast recht. Wie peinlich.
Den Thread bitte schließen.
Oder Löschen, das wär für mich noch besser :oops:

Du bist nicht der Erste und wahrscheinlich auch nicht der letzte dem das passiert,
darum wäre es schön blöd den Thread zu löschen.

Gruß
K-H

Neutral General 27. Jul 2016 23:02

AW: Zugriffsverletzung
 
Zitat:

Zitat von schand99 (Beitrag 1343619)
Oh Mann, du hast recht. Wie peinlich.
Den Thread bitte schließen.
Oder Löschen, das wär für mich noch besser :oops:

Ich hab schon viel peinlichere Threads aufgemacht, die mittlerweile hoffentlich gelöscht (Klatsch&Tratsch) oder vergessen sind :mrgreen: Mach dir nichts draus ;)


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