![]() |
Zugriffsverletzung?
Ich habe in meinem Programm eine function, welche mir einen gegebenen string sortieren soll.
z.B. : '7,3,11,5,1' --> '1,3,5,7,11' Dazu gebe ich meiner function einen string in solch einer Form, also durch Kommas abgetrennte Zahlen. Daraufhin soll es die einzelnen Zahlen separieren und in einem Array aufteilen. Daraufhin durch meinen Such-Algorithmus die einzelnen Glieder jeweils vergleichen und in ein anderes Array in geordneter Reihenfolge kopieren. Und als Ausgabe diese einfach wieder durch Kommas getrennt als einzelnen string ausgeben. Ich denke vom Verfahren her ist mein Code in Ordnung, jedoch bekomme ich immer den folgenden Error: Zugriffsverletzung bei Adresse 00403EBC in Modul 'psort.exe'. Lesen von Adresse 00000004. Hier noch einmal mein Delphi-Code:
Delphi-Quellcode:
Ich hoffe mir kann jemand sagen, worin genau mein Fehler liegt, denn ich habe keine Ahnung was ich falsch gemacht haben könnte. Und schon einmal Danke im vorraus.
unit msort;
interface uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls; type TForm1 = class(TForm) Edit1: TEdit; Edit2: TEdit; procedure Edit1Change(Sender: TObject); private { Private-Deklarationen } public { Public-Deklarationen } end; var Form1: TForm1; implementation function sortString(input: string): string; var i, j, x: integer; output, rest: string; unsorted, sorted: array of string; begin rest:= input; i:= 1; repeat if pos(',', rest) <> 0 then begin unsorted[i]:= copy(rest, i, pos(',', rest) - 1); rest:= copy(rest, pos(',', rest) + 1, length(rest)); i:= i + 1; end; if pos(',', rest) = 0 then begin unsorted[i]:= copy(rest, 1, length(rest)); rest:= ''; end; until rest = ''; for i:= 1 to length(unsorted) do begin x:= i; for j:= 1 to length(unsorted) do begin if (j <> i) and (unsorted[j] <> '') then begin if strtofloat(unsorted[x]) < strtofloat(unsorted[j]) then begin x:= j; end; end; end; sorted[i]:= unsorted[x]; end; output:= sorted[1]; for i:= 2 to length(sorted) do begin output:= output + ',' + sorted[i]; end; result:= output; end; {$R *.dfm} procedure TForm1.Edit1Change(Sender: TObject); begin Edit2.Text:= sortString(Edit1.Text); end; end. :lol: |
AW: Zugriffsverletzung?
Du benutzt ein dynamisches Array of String, setzt aber nirgendwo dessen Größe. Entweder mit SetLength die Größe setzen oder ein statisches Array of String verwenden (das dann immer die angegebene Anzahl von Elementen hat).
Übrigens: Wenn du mit dem Debugger durchsteppst (F7 bzw. F8), wirst du sehen, wo der Fehler auftritt. Allerdings muss die dann markierte Zeile nicht die eigentliche Ursache sein. MfG Dalai |
AW: Zugriffsverletzung?
Danke für deine schnelle Hilfe, ich habe nun probiert die Längen meiner Arrays nach einer anderen function zu setzen, welche mir die nötige Länge ermittelt, bekomme jedoch nun immer einen Error von einer ungültigen Zeigeroperation, aber was ist damit gemeint?
Habe meinen Code um folgendes erweitert:
Delphi-Quellcode:
function testLength(input: string): integer;
var rest: string; counter: integer; begin input:= rest; counter:= 0; repeat if pos(',', rest) <> 0 then begin rest:= copy(rest, pos(',', rest) + 1, length(rest)); counter:= counter + 1; end; if pos(',', rest) = 0 then begin rest:= ''; counter:= counter + 1; end; until rest = ''; result:= counter; end;
Delphi-Quellcode:
setLength(unsorted, testLength(input));
setLength(sorted, testLength(input)); |
AW: Zugriffsverletzung?
Nun, schrumpfen wir's mal auf das Wesentliche zusammen:
Delphi-Quellcode:
Fällt dir was auf?
function testLength(input: string): integer;
var rest: string; counter: integer; begin input:= rest; counter:= 0; result:= counter; end; MfG Dalai |
AW: Zugriffsverletzung?
Statt einem Array of String kannst du auch eine TStringList nehmen.
Setze doch auch mal einen Breakpoint in function sortString bei
Delphi-Quellcode:
(in die Zeile gehen und F5 drücken).
rest:= input;
Wenn du das Programm dann mit F9 startest, hält der Debugger an der Stelle an und du kannst mit F8 durch die Funktion steppen, bzw. mit F7 in eine Funktion reinsteppen. Wenn du mit der Maus dann über Variablen gehst, siehst du auch deren Werte bzw Inhalte. Dadurch kannst du besser nachvollziehen, warum dein Code Probleme macht. |
AW: Zugriffsverletzung?
Tut mir Leid, ich bin damit noch nicht so vertraut:)
Aber was genau ist den nun die Ursache für die 'Ungültige Zeigeroperation', ich verstehe es einfach nicht, für mich ergibt das alles Sinn, leider.^^ Ich weiß nicht einmal was mit einer Zeigeroperation gemeint ist :( |
AW: Zugriffsverletzung?
Teile deinen Code auf, dann wird der übersichtlicher, leichter zum Umsetzen und kommt eigentlich ohne Dokumentation aus.
Delphi-Quellcode:
type
TDynIntArray = array of integer; function StrToIntArray( const AStr : string; const ADelimiter : Char ) : TDynIntArray; begin end; procedure SortIntArray( var AArray : TDynIntArray ); begin end; function IntArrayToStr( const AArray : TDynIntArray; const ADelimiter : Char ) : string; begin end; function SortIntArrayStr( const AStr : string ) : string; var LIntArray : TDynIntArray; begin LIntArray := StrToIntArray( AValue, ',' ); SortIntArray( LIntArray ); Result := IntArrayToStr( LIntArray, ',' ); end; |
AW: Zugriffsverletzung?
Und für die Zukunft schalldest du in den Projektoptionen die Bereichsprüfung an
und lernst wie man den Debugger verwendet. |
AW: Zugriffsverletzung?
Zitat:
Delphi-Quellcode:
Function SortiereZahlen(Eingabe : String) : String;
Var MyList : TSTringList; Begin Result := ''; // setzt Result auf Leerstring; Fehler kannst dann daran erkennen MyList := TStringList.Create; // erzeugen einer Stringliste MyList.Delimiter := ','; // Trennzeichen = Komma MyList.StrictDelimiter := True; // sorgt dafür, daß nur das Komma als Trennzeichen verwendet wird Try MyList.DelimitedText := Eingabe; // hier wird dein String automatisch in einzelne Items zerlegt MyList.Sorted := True; // schaltet die Sortierung der Stringliste ein Result := MyList.DelimitedText; // weist der Rückgabe-Variablen den sortierten String zu Finally MyList.Free; End; End; |
AW: Zugriffsverletzung?
@Perlsau
Das Ergebnis ist dann aber
Delphi-Quellcode:
statt
'1,11,3,5,7'
Delphi-Quellcode:
;)
'1,3,5,7,11'
|
AW: Zugriffsverletzung?
Da hast du auch wieder recht :oops:
Man kann das aber umgehen, indem man einfach alle Strings vor dem Setzen des Sorted-Properties mit der entsprechenden Anzahl von '0' ergänzt :stupid:
Delphi-Quellcode:
Benötigt man die im Rückgabe-String enthaltenen Zahlen danach als Integer-Werte, kann man ohne Probleme die mit voranstehenden Nullen ergänzten Strings zum Umwandeln in Integer verwenden, andernfalls müßte man die Nullen wieder entfernen.
Function FillString(Quelle : String; Zeichen : Char; Anzahl : Integer; Anfang : Boolean) : String;
Var Fuellung : String; begin Result := ''; IF Quelle = '' THEN Exit; Anzahl := Anzahl - Length(Quelle); IF Anzahl < 1 THEN Exit; Fuellung := '' + Zeichen; Fuellung := StrUtils.DupeString(Fuellung,Anzahl); IF Anfang THEN Result := Fuellung + Quelle ELSE Result := Quelle + Fuellung; end; Function SortiereZahlen(Eingabe : String) : String; Var MyList : TSTringList; i : Integer; Begin Result := ''; MyList := TStringList.Create; MyList.Delimiter := ','; MyList.StrictDelimiter := True; Try MyList.DelimitedText := Eingabe; For i := 0 to MyList.Count -1 DO MyList[i] := FillString(MyList,'0',10,True); MyList.Sorted := True; Result := MyList.DelimitedText; Finally MyList.Free; End; |
AW: Zugriffsverletzung?
Ich hätte da eher an so etwas gedacht
Delphi-Quellcode:
Jede Funktion/Prozedur erledigt genau eine Aufgabe. Dadurch bleiben diese übersichtlich, wiederverwend-, test- und wartbar.
program dp_178240;
{$APPTYPE CONSOLE} {$R *.res} {.$DEFINE USE_TYPES} uses {$IFDEF USE_TYPES} Types, // Gibt es ab Delphi XE ??? {$ENDIF} Classes, SysUtils; {$IFNDEF USE_TYPES} type TIntegerDynArray = array of Integer; {$ENDIF} function StrToIntArray( const AStr : string; const ADelimiter : Char ) : TIntegerDynArray; var LStrings : TStrings; LIdx : Integer; begin LStrings := TStringList.Create; try LStrings.Delimiter := ADelimiter; LStrings.DelimitedText := AStr; SetLength( Result, LStrings.Count ); for LIdx := 0 to LStrings.Count - 1 do begin Result[LIdx] := StrToInt( LStrings[LIdx] ); end; finally LStrings.Free; end; end; function IntArrayToStr( const AIntArray : TIntegerDynArray; const ADelimiter : Char ) : string; var LStrings : TStrings; LIdx : Integer; begin LStrings := TStringList.Create; try LStrings.Delimiter := ADelimiter; for LIdx := low( AIntArray ) to high( AIntArray ) do begin LStrings.Add( IntToStr( AIntArray[LIdx] ) ); end; Result := LStrings.DelimitedText; finally LStrings.Free; end; end; procedure SortIntArray( var AIntArray : TIntegerDynArray ); var LCurrent : Integer; LCompare : Integer; LTemp : Integer; begin // Simple Bubble-Sort algo for LCurrent := low( AIntArray ) to high( AIntArray ) - 1 do begin for LCompare := LCurrent + 1 to high( AIntArray ) do begin if AIntArray[LCurrent] > AIntArray[LCompare] then begin LTemp := AIntArray[LCurrent]; AIntArray[LCurrent] := AIntArray[LCompare]; AIntArray[LCompare] := LTemp; end; end; end; end; function SortIntArrayStr( const AStr : string; const ADelimiter : Char = ',' ) : string; var LIntArray : TIntegerDynArray; begin LIntArray := StrToIntArray( AStr, ADelimiter ); SortIntArray( LIntArray ); Result := IntArrayToStr( LIntArray, ADelimiter ); end; procedure Test; var LTest : string; begin LTest := '7,3,11,5,1'; Writeln( LTest, ' => ', SortIntArrayStr( LTest ) ); end; begin try Test; except on E : Exception do Writeln( E.ClassName, ': ', E.Message ); end; ReadLn; end. |
AW: Zugriffsverletzung?
Zitat:
Delphi-Quellcode:
// Nur mit TStringList
function StringListIntSort( List : TStringList; Index1, Index2 : Integer ) : Integer; begin Result := StrToInt( List[Index1] ) - StrToInt( List[Index2] ); end; function SortIntArrayStr( const AStr : string; const ADelimiter : Char = ',' ) : string; var LStrings : TStringList; begin LStrings := TStringList.Create; try LStrings.Delimiter := ADelimiter; LStrings.DelimitedText := AStr; LStrings.CustomSort( StringListIntSort ); Result := LStrings.DelimitedText; finally LStrings.Free; end; end; |
Alle Zeitangaben in WEZ +1. Es ist jetzt 05:27 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