Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi EAccessViolation bei Bubblesort (https://www.delphipraxis.net/100990-eaccessviolation-bei-bubblesort.html)

Dyvil 6. Okt 2007 16:30


EAccessViolation bei Bubblesort
 
Hi, ich bekomme folgende Fehlermeldung beim Button-Klick, der Bubblesort eines array of records durchführen soll. Es geht, wie ihr sehen könnt, um einen Abiturrechner, bei dem durch Bubblesort die Noten sortiert werden sollen!


http://img120.imageshack.us/img120/6119/fehlerle8.jpg
Delphi-Quellcode:
var
  Abiturrechner: TAbiturrechner;
  List : TStringList;

type
  TNoteneintrag = record
    Editfeld: string;
    Notenpunkte: Integer;
       end;
  Blg = array[1..10] of TNoteneintrag;


implementation

uses fAbout;

{$R *.dfm}

procedure BubbleSort(var List: Blg);
var
  done: boolean;
  i, n: integer;
  Dummy: string;
begin
  //n := List[i].Count;
  n := 5;
  repeat
    done := true;
    for i := 0 to n - 1 do
      if List[i].Notenpunkte > List[i + 1].Notenpunkte then
      begin
        Dummy := List[i].Editfeld;
        List[i].Notenpunkte := List[i + 1].Notenpunkte;
        List[i + 1].Editfeld := Dummy;
        done := false;
      end;
  until done;
end;

procedure TAbiturrechner.Button1Click(Sender: TObject);
var noten : Blg;
var s : string;
var i,u : integer;

begin
for i := 1 to 5 do begin
s := Edit1.Text;
u := StrToInt(s);
noten[i].Notenpunkte := u;
noten[i].Editfeld := s;
end;
Bubblesort(noten);
end;

end.

DeddyH 6. Okt 2007 16:34

Re: EAccessViolation bei Bubblesort
 
Versuch es mal im Bubblesort statt mit
Delphi-Quellcode:
for i := 0 to n - 1 do
mit
Delphi-Quellcode:
for i := Low(List) to High(List) - 1 do
Blg ist als Array von 1 bis 10 deklariert, Du willst aber auf Element 0 zugreifen.

Dyvil 6. Okt 2007 16:35

Re: EAccessViolation bei Bubblesort
 
wunderbar, vielen Dank!

Dyvil 6. Okt 2007 16:39

Re: EAccessViolation bei Bubblesort
 
nochmal schnell eine andere Frage: Was ist hier falsch in der Schleife?

Delphi-Quellcode:
for i := 1 to 5 do begin
//s := Edit1.Text;
s := 'Edit'+IntToStr(i)+'.Text';

Progman 6. Okt 2007 16:43

Re: EAccessViolation bei Bubblesort
 
s nimmt 5 mal einen anderen Wert an ('Edit1.Text'...'Edit5.Text'. Das macht irgendwie keinen Sinn ;)

DeddyH 6. Okt 2007 16:46

Re: EAccessViolation bei Bubblesort
 
Ich denke, was Du beabsichtigst, ist in etwa dies hier:
Delphi-Quellcode:
for i := 1 to 5 do
  s := TEdit(FindComponent('Edit' + inttostr(i))).Text;

Dyvil 6. Okt 2007 16:46

Re: EAccessViolation bei Bubblesort
 
Zitat:

Zitat von Progman
s nimmt 5 mal einen anderen Wert an ('Edit1.Text'...'Edit5.Text'. Das macht irgendwie keinen Sinn ;)

ja genau, so hatte ich mir das auch gedacht, damit die Noten der 5 verschiedenen Editfelder sortiert werden....

Dyvil 6. Okt 2007 16:53

Re: EAccessViolation bei Bubblesort
 
vielen Dank für eure Hilfe. Jetzt funktioniert eigentlich alles, jedoch hab ich jetzt mal probeweise die ersten 2 bubblesort werte ausgeben lassen und die sind jedes mal "3", auch wenn alle Noten "10" sind... :wall:

Dyvil 9. Okt 2007 10:33

Sortierung von Strings beim Abirechner...
 
erstmal vielen Dank für eure Hilfe! besonderen Dank an DeddyH!
Bubblesort funktioniert für die Sortierung der Noten schon wunderbar, aber die Fächer werden nicht wirklich sortiert.Anstatt diese so zu sortieren, dass am Ende die Noten wieder zu den Fächern passen, werden die Fächer auch mit den Noten befüllt und sortiert von 1 bis ...
Ich kann mir den Fehler nicht wirklich erklären, weil die Sortierung der Noten wunderbar funktioniert und diese durch "StrToInt" eingelesen werden, also kann bei den strings nicht wirklich was falsch sein, oder?

Delphi-Quellcode:
unit fAbiturrechner;
var
  Abiturrechner: TAbiturrechner;
  List : TStringList;

type
  TNoteneintrag = record
    Editfeld: string;
    Notenpunkte: Integer;
       end;
  Blg = array[1..5] of TNoteneintrag;

implementation

procedure SwapIntegers(var a, b : integer);
begin
  a := a xor b;
  b := b xor a;
  a := a xor b;
end;

procedure BubbleSort(var List: Blg);
var
  done: boolean;
  i, n: integer;
  Dummy: string;
begin
  n := High(List);
  repeat
    done := true;
      for i := Low(List) to High(List) - 1 do
      if List[i].Notenpunkte > List[i + 1].Notenpunkte then
      begin
        Dummy := List[i].Editfeld;
        List[i].Editfeld := List[i+1].Editfeld;
        List[i + 1].Editfeld := Dummy;
        SwapIntegers(List[i].Notenpunkte,List[i + 1].Notenpunkte);
        done := false;
      end;
  until done;
end;

procedure TAbiturrechner.Button1Click(Sender: TObject);
var noten : Blg;
var s,z : string;
var i,u, t : integer;
begin
FillChar(noten,SizeOf(noten),#0);
for i := 1 to 5 do begin
s := TEdit(FindComponent('Edit' + inttostr(i))).Text; //<-- string wird z.b. mit "Edit1.Text" gefüllt
u := StrToInt(s);                                     //<-- Noten werden eingelesen
noten[i].Notenpunkte := u;
noten[i].Editfeld := s;
end;
Bubblesort(noten);
  for i := Low(noten) to High(noten) do
    ShowMessage(Format('%d',[noten[i].Notenpunkte]));

z := noten[1].Editfeld;  //<-- Kontrolle! Hier sollte das Editfeld mit der kleinsten Punktzahl stehen
showmessage(z);
end;

end.

DeddyH 9. Okt 2007 10:52

Re: EAccessViolation bei Bubblesort
 
Und so?
Delphi-Quellcode:
procedure SwapNoten(var a,b: TNoteneintrag);
var dummy: TNotenEintrag;
begin
  dummy := a;
  a := b;
  b := dummy;
end;

procedure BubbleSort(var List: Blg);
var
  done: boolean;
  i: integer;
begin
  repeat
    done := true;
      for i := Low(List) to High(List) - 1 do
      if List[i].Notenpunkte > List[i + 1].Notenpunkte then
      begin
        SwapNoten(List[i],List[i + 1]);
        done := false;
      end;
  until done;
end;

Dyvil 9. Okt 2007 11:03

Re: EAccessViolation bei Bubblesort
 
nee das funktioniert auch nicht, immernoch der gleiche fehler...

quendolineDD 9. Okt 2007 11:15

Re: EAccessViolation bei Bubblesort
 
Hilft eventuell das hier weiter?

EDIT:

Da ich oben sehe, das ein Speicherfehler vorliegt, du benutzt doch eine Liste, wurde diese auch richtig instanziert?

Eventuell hilft es dir, wenn du mal unter Optionen -> Compiler -> Optimierung uncheckst und dann mit F4 und F7 deinen Code einzeln durchguckst. Wenn du dann mit der Maus drüber gehst, kannst du dir die Werte der Variablen zur Laufzeit anzeigen lassen :o)

EDIT2:

Gerade mal deinen Quelltext angeschaut. Also du hast ja ein
Delphi-Quellcode:
var List: TStringList;
Du solltest hier, bevor du auf diese Liste irgendwie verweist und Werte schreiben willst, diese auch mal instanzieren. BVis jetzt weiß Delphi nämlich noch nicht, wo diese im Speicher sich befindet.

Füge mal ein
Delphi-Quellcode:
List:= TStringList.Create;
hinzu

Dyvil 9. Okt 2007 11:36

Re: EAccessViolation bei Bubblesort
 
Delphi-Quellcode:
procedure BubbleSort(var List: Blg);
var
  done: boolean;
  i, n: integer;
  Dummy: string;
begin
  List:= TStringList.Create;
dann kommt ein fehler, dass "blg" und "TStringlist" inkompatible Typen sind

Edit: ich habe das "list:= TStringList.Create" mal als formcreate prozedur geschrieben, aber dann kommt der ursprüngliche Fehler immernoch!

quendolineDD 9. Okt 2007 11:45

Re: EAccessViolation bei Bubblesort
 
Tut mir leid, war mein Fehler. Das kannst du wieder wegmachen ;o)

Ich schätze mal deine Bereichsverletzung kommt aus der Zeile.
Delphi-Quellcode:
for i := Low(List) to High(List) - 1 do
Mache hier draus mal
Delphi-Quellcode:
for i := Low(List) to High(List) - 2 do
Wenn du dir das hier mal anschaust
Delphi-Quellcode:
procedure BubbleSort(Items: TStrings);
var
  done: boolean;
  i, n: integer;
  Dummy: string;
begin
  n := Items.Count;

  repeat
    done := true;
    for i := 0 to n - 2 do
      if Items[i] > Items[i + 1] then
      begin
        Dummy := Items[i];
        Items[i] := Items[i + 1];
        Items[i + 1] := Dummy;

        done := false;
      end;
  until done;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  BubbleSort(Listbox1.Items);
end;
http://www.dsdt.info/tipps/?id=368
Hab ich in #12 schon gepostet ;)

Dyvil 9. Okt 2007 11:53

Re: EAccessViolation bei Bubblesort
 
das hier funktioniert so nicht, weil er dann nur 4 statt 5 Werte sortiert und den 5. Wert einfach an den Schluss hängt. Die Sortierung wird dann also falsch:
Delphi-Quellcode:
for i := Low(List) to High(List) - 2 do
Den Link zum Bubblesort habe ich mir schon angeguckt, jedoch habe ich ein record und kein einfaches array....

quendolineDD 9. Okt 2007 12:03

Re: EAccessViolation bei Bubblesort
 
Hast du mal geschaut, an welcher Stelle er den Fehler bringt?

Dyvil 9. Okt 2007 12:08

Re: EAccessViolation bei Bubblesort
 
der Fehler müsste schon relativ früh auftauchen glaube ich. Wenn ich Bubblesort einfach rauskommentiere, steht im string nicht das, was da stehen soll (also das Editfeld). Also müsste theoretisch beim Einlesen des stringwertes ein Fehler sein, aber andererseits klappt das "StrToInt" bei den Noten wunderbar, somit weiß der Rechner ja eigentlich, welches Editfeld gemeint ist... Eigentlich...

quendolineDD 9. Okt 2007 12:26

Re: EAccessViolation bei Bubblesort
 
Delphi-Quellcode:
procedure TAbiturrechner.Button1Click(Sender: TObject);
var noten : Blg;
    i    : integer;

begin
for i := 1 to 5 do begin
noten[i].Notenpunkte := strtoint(Edit1.Text);
noten[i].Editfeld := Edit1.Text;
end;
Bubblesort(noten);
end
Das ist ja eigentlich keine wirkliche Änderung :\

EDIT: Wieso eigentlich 5 mal das gleiche aus Edit1.Text auslesen?
Und warum genau 5 mal, wenn doch Blg ein Array[1..10] ist ?

Dyvil 9. Okt 2007 12:36

Re: EAccessViolation bei Bubblesort
 
da wird nichts 5 mal aus Edit1.Text ausgelesen, das musst du falsch verstanden haben. Schaue dir doch nochmal meinem Post #9 an, da steht:
Delphi-Quellcode:
s := TEdit(FindComponent('Edit' + inttostr(i))).Text;

DeddyH 9. Okt 2007 12:42

Re: EAccessViolation bei Bubblesort
 
Da steht dann aber nicht "Edit1.Text" drin, sondern der Inhalt von Edit1 ;)

Dyvil 9. Okt 2007 12:43

Re: EAccessViolation bei Bubblesort
 
Zitat:

Zitat von DeddyH
Da steht dann aber nicht "Edit1.Text" drin, sondern der Inhalt von Edit1 ;)

ah...........................................
Du hast natürlich Recht!

Edit: funktioniert jetzt so, wie es soll! :hello: :hello: :hello: :hello: :hello: :hello:

DeddyH 9. Okt 2007 12:45

Re: EAccessViolation bei Bubblesort
 
Delphi-Quellcode:
s := TEdit(FindComponent('Edit' + inttostr(i))).Name;
So sollte es gehen (obwohl es eigentlich Quatsch ist).


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