![]() |
Problem bei SetLength()
Hallo Community,
ich habe ein problem mit dem SetLength() Befehl aus Pascal. Ich nutze den Befehl, um einen dynamischen array auf die Länge X zu setzen. Rufe ich die prozedure ein zweites Mal auf, dieses Mal jedoch mit einem Wert <X, bekomme ich einen External SIGSEGV Error. Kann mir jemand erklären, warum dies so ist, bzw. wie ich diesen Fehler umgehen und ausbessern kann? Ich nutze Lazarus 1.2.6, jedoch habe ich in der betroffenen Unit die Codierung auf Delphi gestellt ({$mode delphi}) Grüße |
AW: Problem bei SetLength()
Zeig mal Code!
|
AW: Problem bei SetLength()
Der Code ist an sich eigentlich relativ simple, es wird nur eine Datei eingelesen:
Wie schon gesagt, lade ich eine Datei, funktioniert der Code ohne Probleme, lade ich jedoch später eine neue (kleinere, d.h. kleinere Array-länge) Datei, gibt es den Fehler mit SetLength()
Delphi-Quellcode:
var
MTL: array of record //only editable values :) Name: String; MatClass: array[0..3] of word; Diffuse, Ambient, Specular, Reflect2: TColor; XDiffuse, XSpecular, Specular2: TColor; TexName:String; Transparency:Byte; SpecProbs, Fresnel: array[0..2] of word; FallOff: array[0..1] of word; end; procedure LoadMTL(a:String); var f:Textfile; s:String; i:Integer; begin SetLength(MTL, TRXHead.Materials); {Fehler beim zweiten Laden} AssignFile(f,a); Reset(f); ReadLn(f,s); //ColSetInf for i:=0 to TRXHead.Materials-1 do begin ReadLn(f,s); //Empty line ReadLn(f,s); MTL[i].Name:=s; ReadLn(f,s); Delete(s,1,9); MTL[i].MatClass[0]:=StrToInt(s[1]+s[2]); MTL[i].MatClass[1]:=StrToInt(s[4]+s[5]); MTL[i].MatClass[2]:=StrToInt(s[7]+s[8]); MTL[i].MatClass[3]:=StrToInt(s[10]+s[11]); ReadLn(f,s); MTL[i].Diffuse:=ReadColorFromLine(s); ReadLn(f,s); MTL[i].Ambient:=ReadColorFromLine(s); ReadLn(f,s); MTL[i].Specular:=ReadColorFromLine(s); ReadLn(f,s); MTL[i].Reflect2:=ReadColorFromLine(s); ReadLn(f,s); MTL[i].Specular2:=ReadColorFromLine(s); ReadLn(f,s); MTL[i].XDiffuse:=ReadColorFromLine(s); ReadLn(f,s); MTL[i].XSpecular:=ReadColorFromLine(s); ReadLn(f,s); SetLength(s, Length(s)-1); Delete(s, 1, 10); MTL[i].TexName:=s; ReadLn(f,s); //Tex2 ReadLn(f,s); //Tex3 ReadLn(f,s); //TexFlags ReadLn(f,s); //TexOffset ReadLn(f,s); //TexScale ReadLn(f,s); //TexAngle ReadLn(f,s); Delete(s,1,6); MTL[i].Transparency:=StrToInt(s); ReadLn(f,s); Delete(s,1,10); MTL[i].SpecProbs[0]:=StrToInt(s[1]+s[2]+s[3]);MTL[i].SpecProbs[1]:=StrToInt(s[5]+s[6]+s[7]);MTL[i].SpecProbs[2]:=StrToInt(s[9]+s[10]+s[11]); ReadLn(f,s); Delete(s,1,8); MTL[i].Fresnel[0]:=StrToInt(s[1]+s[2]+s[3]);MTL[i].Fresnel[1]:=StrToInt(s[5]+s[6]+s[7]);MTL[i].Fresnel[2]:=StrToInt(s[9]+s[10]+s[11]); ReadLn(f,s); Delete(s,1,8); MTL[i].FallOff[0]:=StrToInt(s[1]+s[2]+s[3]);MTL[i].FallOff[1]:=StrToInt(s[5]+s[6]+s[7]); end; CloseFile(f); end; |
AW: Problem bei SetLength()
Zitat:
1)...... (das vergessen wir da die Formatierung mich irregeleitet hat) 2) was ist TRXHead.Materials ?? Gruß K-H |
AW: Problem bei SetLength()
Wegen den Longstrings? RefCount?
|
AW: Problem bei SetLength()
TRXHead.Materials ist ein Integerwert aus einer zugehörigen Datei, welcher größer 0 ist.
In beiden Fällen liefert mir dieser Wert einen gültigen wert, beim ersten Mal (die größere Datei) ist der Wert 2, bei der zweiten Datei ist der Wert 1. Ich nehme an, dass sich das erste genannte Problem erledigt hat (?) |
AW: Problem bei SetLength()
Zitat:
Mit Sicherheit greifst Du irgendo entweder auf MTL[] oder s[] auf einen ungültigen Indexwert zu. Der entscheidende Code-Abschitt fehlt. |
AW: Problem bei SetLength()
Der String dürfte dir auch Probleme bereiten. Oder willst du wirklich die Speicheradresse in dem Record haben?
|
AW: Problem bei SetLength()
Die Fehlermeldung kann nur dort passieren, da ich - wenn ich vor dem SetLength()und nach dem SetLength()einen ShowMessage-Dialog einbaue - nur den ersten Dialog bekomme, bevor die Fehlermeldung kommt.
Sollte ich auf einen ungültigen Wert von MTL[] oder s[] zugreifen, müsste es doch auch schon beim ersten Mal nicht funktionieren, oder? Luckie, was verstehst du unter "Probleme bereiten"? Kannst du dabei etwas genauer werden? Danke im Vorraus. |
AW: Problem bei SetLength()
Zitat:
Wenn der Fehler wirklich in
Delphi-Quellcode:
auftritt, sollte jemand an entweder dem Array selbst oder den enthaltenen Strings etwas kaputtgemacht haben.
setLength
Du machst doch sicher noch etwas zwischen den Aufrufen von
Delphi-Quellcode:
. Tritt der Fehler auch auf, wenn du die zwei
LoadMTL
Delphi-Quellcode:
-Aufrufe direkt nacheinander ausführst? Beziehungsweise, stellst du irgendwelche versauten Speicherarithmetik-Sachen mit den Daten an?
LoadMTL
|
AW: Problem bei SetLength()
Prüfe doch mal beim 2ten laden welchen wert TRXHead.Materials denn nun wirklich hat.
Beim laden kann ich nirgends erkennen wo Materials ein neuer wert zugewiesen wird. Eventuell.. SetLength(MTL, TRXHead.Materials); nach dem öffen der Textdatei einfügen nicht vorher wenn Materials den neuen wert aus der Text Datei bekommt. gruss |
AW: Problem bei SetLength()
BUG hatte die Lösung. Lade ich beide Dateien direkt hintereinander, geht es ohne Probleme.
Es muss tatsächlich an irgendeinem Code dazwischen liegen. Dummerweise mache ich zwischen den eigentlichen beiden Aufrufen der LoadMTL Prozedur nichts anderes, als die geladenen Daten mittels OpenGL zu rendern. Aber dabei wird ja eigentlich nichts an dem Record bzw an dem array geändert, denn das Rendern ist ja ein reiner Lesevorgang. Übersehe ich dabei etwas? TRXHead.Materials wird in einer anderen Lade-Prozedur zugewiesen(da sich der Wert in einer anderen Datei befindet), welche vor der LoadMTL() prozedure aufgerufen wird. Ich könnte auch anbieten, dass ich Interessierten den Code per Email zukommen lasse, damit dort ein Blick hineingeworfen werden kann. Ich möchte den Code allerdings leider nicht öffentlich teilen. |
AW: Problem bei SetLength()
Zitat:
Wenn ja hilft dir nur debuggen. gruss |
AW: Problem bei SetLength()
Zitat:
|
AW: Problem bei SetLength()
Zitat:
Der Wert ist vor dem aufrufen zugewiesen, er ist bei der größeren Datei bei 2, bei der zweiten Datei bei 1. Beides sind meines Wissens nach eine gültige Zahl für SetLength() Ich bin nur ein Hobby-Programmmierer, ohne jegliches Informatikvorwissen. Inwiefern soll mit denn dann "nur debuggen" ausführen? Vielleicht ist es noch hilfreich, wenn ich die Assemblernachricht angebe: Zitat:
|
AW: Problem bei SetLength()
Hallo,
also zwischen den beiden Aufrufen renderns du nur, nehmen wir an, du rufts da eine Funktion falsch auf, und dieses FALSCH aufrufen, führt dann am Ende zu dem von dir beschriebenen Problem. Du möchtest hier nicht deinen ganzen Quellcode posten, das ist soweit ok. Aber dann müsstest du auch das Problem grundsätzlich alleine lösen. Es macht wenig Sinn, ein Problem nur halb zu posten, und dann zu erwarten, dass die anderen sich die andere Hälfte dann selber holen mfg frank |
AW: Problem bei SetLength()
Zitat:
Die Fehlermeldung, welche uns der TE gepostet hat, wird NICHT durch die Funktion SetLength() erzeugt. Egal was in "TRXHead.Materials" steht, wirft SetLength() niemals diesen Exceptiontyp. |
AW: Problem bei SetLength()
Ich habe es durchaus aufgenommen, dass der Fehler nicht von SetLength erzeugt wird, jedoch kommt die Fehlermeldung exakt bei dieser Zeile im Code.
Sonderlich glücklich bin ich bei der folgeden Handlung nicht, aber da das Projekt ja noch nicht ganz fertig ist, kann man ja ein Auge zudrücken. Anbei sämtliche Projektdateien, sowie die beiden Beispieldateien. Auf Wunsch kann ich mehr Beispieldateien verfügbar machen. Die zu ladendenden Dateien sind die *.trx Dateien, neben dieser Datei werden auch weitere Dateien, welche zum darstellen (via OpenGL) benötigt werden, geladen. Download: ![]() |
AW: Problem bei SetLength()
Bei mir ist das Programm überhaupt nicht lauffähig.
1. Fehler in Zeile 257 der Mainunit.pas in TForm1.LoadShader.
Delphi-Quellcode:
ProgramO:=glCreateProgram;
|
AW: Problem bei SetLength()
Zitat:
Wenn man keine besseren Analysewerkzeuge hat, könnte man zum Beispiel versuchen, systematisch Programmbestandteile zwischen den Aufrufen auszukommentieren bis es wieder funktioniert. |
AW: Problem bei SetLength()
Zitat:
Ich habe den Strings im Betroffenen Record auf eine feste Länge reduziert, somit kommt beim mehrmaligen Laden nun kein Fehler mehr. Dafür kommt nun beim Schließen des Programms die SIGSEGV Meldung, aber immerhin wurde dieses Problem gelöst :thumb: |
AW: Problem bei SetLength()
Zitat:
|
AW: Problem bei SetLength()
Wenn das Problem also woanders liegen sollte - ist es dann möglich, dass jemand für mich über den Code schaut? Ich bin mir immer noch im unklaren, woher genau dieser Fehler kommen könnte.
Das Programm (welches zumindest bei mir Lauffähig ist) gibts auf Seite 2 |
AW: Problem bei SetLength()
Delphi-Quellcode:
Hier ist schon mal eine Verletzung der Untergrenze.
var
c:array[1..256] of PAnsiChar; LoadCPO BlockRead(f, c[0], 4); Zitat:
Kein DPR, DFM.. Ja Lazarus, deshalb bin ich raus. Vielleicht hilft dir dieser Fehler schon mal. gruss |
AW: Problem bei SetLength()
Vielen dank schoneinmal für diesen Hinweis! Wurde ausgebessert :wink:
Ja, bei mir lief das davor ohne Probleme, jedoch kommt der Fehler nach dem Ausbessern immer noch. |
AW: Problem bei SetLength()
Hört sich für mich so an als ob Du keine Breichsüberprüfung eingestellt hättest. Ich würde es mal mit versuchen.
Gruß K-H |
AW: Problem bei SetLength()
Zitat:
Zitat:
gruss |
AW: Problem bei SetLength()
Zitat:
Da ich selber noch nicht all zu lange bei Lazarus bin, habe ich gar nicht gewusst, dass dies Standardmäßig abgeschaltet ist, da diese Funktion bei Delphi ja automatisch ging (wie gesagt, ich bin ja auch nur hobbymäßig dabei). Nach dem Einstellen wurde der Fehler erkannt & gebannt. Vielen Dank für alle Helfer. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 08:53 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