Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Zugriffsverletzung beim Freigeben einer TStringList (https://www.delphipraxis.net/96213-zugriffsverletzung-beim-freigeben-einer-tstringlist.html)

tr909 20. Jul 2007 08:55


Zugriffsverletzung beim Freigeben einer TStringList
 
Moin. Ich schreibe mir gerade eine Klasse zum einlesen und verarbeiten von csv-Files. Nun kommt es bei einer Testdatei (bei einer anderen tritt der Fehler nicht auf) zu einer Zugriffsverletzung bei "s.Free"
content ist deklariert als ARRAY of TStrings;

Delphi-Quellcode:
procedure TCsvDB.LoadFromFile(const fname: string);
var
  s : TStrings;
  i: Integer;
begin
try
  s := TStringList.Create;
  s.LoadFromFile(fname);
  Header.Delimiter := ';';
  Header.StrictDelimiter := true;
  Header.DelimitedText := s[0];
  headerCount := header.Count;
  lineCount := s.Count - 1;
  ShowMessage (IntToStr(linecount));
  setlength(Content,lineCount);
  showmessage ('setlength');
  for i := 1 to lineCount do
  begin
    Content[i] := TStringList.Create;
    Content[i].Delimiter := ';';
    Header.StrictDelimiter := true;
    Content[i].DelimitedText := s[i];
  end;
finally
  s.Free;
end;
end;
Wäre nett wenn mir jemand helfen könnte.

Gruß
tr909

sirius 20. Jul 2007 09:01

Re: Zugriffsverletzung beim Freigeben einer TStringList
 
for i:=0 to linecount-1 do

Bernhard Geyer 20. Jul 2007 09:04

Re: Zugriffsverletzung beim Freigeben einer TStringList
 
Zitat:

Zitat von sirius
for i:=0 to linecount-1 do

nee:
Delphi-Quellcode:
lineCount := s.Count - 1;

SirThornberry 20. Jul 2007 09:06

Re: Zugriffsverletzung beim Freigeben einer TStringList
 
Zitat:

Zitat von Bernhard Geyer
Zitat:

Zitat von sirius
for i:=0 to linecount-1 do

nee:
Delphi-Quellcode:
lineCount := s.Count - 1;

Genau, und Dadurch wird die Größe von Content 1 zu klein

FAlter 20. Jul 2007 09:08

Re: Zugriffsverletzung beim Freigeben einer TStringList
 
Hi,

Zitat:

Zitat von sirius
for i:=0 to linecount-1 do

Nein, dass ist es nicht - Linecount := s.Count - 1 und Zeile 0 ist der Header.

[ot] btw: Wenn es 0 Zeilen gibt, dass würde es zu einer anderen Exception kommen. Und für den Fall, dass vorher bereits eine CSV geladen wurde, solltest du die StringLists im Content-Array freigeben. Außerdem würde ich den Delimiter und StrictDelimiter nicht hardcoden, sodass deine Klasse später besser nutzbar wird. [/ot]

Bist du sicher, dass das Problem in der Zeile mit s.Free liegt? Oder kommt die AV woanders? Ich sehe keinen Grund für eine AV, außer, dass es bereits ein Problem beim Create gibt. Dann müsstest du das Create vor Try setzen.

Mfg
FAlter

[edit]Tja, dyn. Arrays beginnen aber mit 0, also wars doch nicht so falsch...
Delphi-Quellcode:
  for i := 0 to lineCount - 1 do
  begin
    Content[i] := TStringList.Create;
    Content[i].Delimiter := ';';
    Header.StrictDelimiter := true;
    Content[i].DelimitedText := s[i+1];
  end;
[/edit]

sirius 20. Jul 2007 09:11

Re: Zugriffsverletzung beim Freigeben einer TStringList
 
Zitat:

Zitat von Bernhard Geyer
Zitat:

Zitat von sirius
for i:=0 to linecount-1 do

nee:
Delphi-Quellcode:
lineCount := s.Count - 1;

Doch:
Delphi-Quellcode:
setlength(Content,lineCount);
for i := 1 to lineCount do
begin
  Content[i] := ...
Und beim letzten überschreibt er irgendetwas unvorhersehbares.
[Edit]Und wie ich unseren Compiler so kenne liegt nämlich das Array mit den Pointer direkt neben der Instanz von s[/Edit]


Zitat:

Zitat von SirThornberry
Genau, und Dadurch wird die Größe von Content 1 zu klein

Ja, das auch. Aber das hätte er sicherlich noch bemerkt. Zumal ich vermute, dass es ähnlich wie die showmessages (mehr oder weniger) wirres rumprobiere ohne Ziel war um den Fehler zu finden und demnächst eh wieder rausfliegt.

tr909 20. Jul 2007 09:37

[erl]Re: Zugriffsverletzung beim Freigeben einer TStringList
 
Jaja, dyn. Arrays beginnen bei 0. :roll:
Nun funktioniert es. Vielen Dank

Delphi-Quellcode:
procedure TCsvDB.LoadFromFile(const fname: string);
var
  s : TStrings;
  i: Integer;
begin
try
  s := TStringList.Create;
  s.LoadFromFile(fname);
  Header.Delimiter := Delimiter;
  Header.StrictDelimiter := StrictDelimiter;
  Header.DelimitedText := s[0];
  headerCount := header.Count;
  for i := 0 to linecount - 1 do
    Content[i].Free;
  lineCount := s.Count - 1;
  setlength(Content,lineCount);
  for i := 0 to lineCount-1  do
  begin
    Content[i] := TStringList.Create;
    Content[i].Delimiter := Delimiter;
    Header.StrictDelimiter := StrictDelimiter;
    Content[i].DelimitedText := s[i+1];
  end;
finally
  s.Free;
end;
end;
Gruß
tr909

Muetze1 20. Jul 2007 09:43

Re: Zugriffsverletzung beim Freigeben einer TStringList
 
Verschiebe das "Try" noch um eine Zeile nach unten, also nach das s := TStringList.Create


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