Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Problem bei SetLength() (https://www.delphipraxis.net/186275-problem-bei-setlength.html)

the3dcloser 19. Aug 2015 14:27


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

TiGü 19. Aug 2015 14:50

AW: Problem bei SetLength()
 
Zeig mal Code!

the3dcloser 19. Aug 2015 15:23

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;

p80286 19. Aug 2015 15:41

AW: Problem bei SetLength()
 
Zitat:

Zitat von the3dcloser (Beitrag 1312740)
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);
...
end;

Das sollte eigentlich überhaupt nicht compilieren.
1)...... (das vergessen wir da die Formatierung mich irregeleitet hat)
2) was ist TRXHead.Materials ??

Gruß
K-H

Mavarik 19. Aug 2015 15:46

AW: Problem bei SetLength()
 
Wegen den Longstrings? RefCount?

the3dcloser 19. Aug 2015 15:56

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 (?)

BadenPower 19. Aug 2015 16:04

AW: Problem bei SetLength()
 
Zitat:

Zitat von the3dcloser (Beitrag 1312733)
Rufe ich die prozedure ein zweites Mal auf, dieses Mal jedoch mit einem Wert <X, bekomme ich einen External SIGSEGV Error.

Der "External SIGSEGV Error" wird nicht bei der Benutzung von SetLength ausgegeben, selbst dann nicht, wenn neagative Werte oder ein Zeichen übergeben wird.

Mit Sicherheit greifst Du irgendo entweder auf MTL[] oder s[] auf einen ungültigen Indexwert zu.

Der entscheidende Code-Abschitt fehlt.

Luckie 19. Aug 2015 17:20

AW: Problem bei SetLength()
 
Der String dürfte dir auch Probleme bereiten. Oder willst du wirklich die Speicheradresse in dem Record haben?

the3dcloser 19. Aug 2015 17:48

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.

BUG 19. Aug 2015 19:04

AW: Problem bei SetLength()
 
Zitat:

Zitat von Luckie (Beitrag 1312760)
Der String dürfte dir auch Probleme bereiten. Oder willst du wirklich die Speicheradresse in dem Record haben?

Ich denke schon, es sieht aus, als ob ein Record einfach nur als "dummer" Datensatz ohne Logik benutzt wird.


Wenn der Fehler wirklich in
Delphi-Quellcode:
setLength
auftritt, sollte jemand an entweder dem Array selbst oder den enthaltenen Strings etwas kaputtgemacht haben.
Du machst doch sicher noch etwas zwischen den Aufrufen von
Delphi-Quellcode:
LoadMTL
. Tritt der Fehler auch auf, wenn du die zwei
Delphi-Quellcode:
LoadMTL
-Aufrufe direkt nacheinander ausführst? Beziehungsweise, stellst du irgendwelche versauten Speicherarithmetik-Sachen mit den Daten an?

EWeiss 19. Aug 2015 19:42

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

the3dcloser 19. Aug 2015 19:50

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.

EWeiss 19. Aug 2015 19:56

AW: Problem bei SetLength()
 
Zitat:

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.
Sorry und du bist dir sicher das du das auch wirklich tust.? vor dem zweiten laden?
Wenn ja hilft dir nur debuggen.

gruss

Mavarik 19. Aug 2015 20:04

AW: Problem bei SetLength()
 
Zitat:

Zitat von the3dcloser (Beitrag 1312763)
Luckie, was verstehst du unter "Probleme bereiten"? Kannst du dabei etwas genauer werden?

Daher auch meine Frage... Longstring ist eine Refrenz... "nur ein Pointer" mit Refcount usw...

the3dcloser 20. Aug 2015 12:01

AW: Problem bei SetLength()
 
Zitat:

Zitat von EWeiss (Beitrag 1312783)
Sorry und du bist dir sicher das du das auch wirklich tust.? vor dem zweiten laden?
Wenn ja hilft dir nur debuggen.


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:

Zitat von Assembler
00403514 0f1004c6 movups (%esi,%eax,8),%xmm0

Ich persönlich kann damit nichts anfangen :/

frankyboy1974 20. Aug 2015 12:24

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

BadenPower 20. Aug 2015 12:54

AW: Problem bei SetLength()
 
Zitat:

Zitat von the3dcloser (Beitrag 1312855)
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()

Nochmals zum mitschreiben:

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.

the3dcloser 20. Aug 2015 13:17

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: http://www.file-upload.net/download-...4/Tool.7z.html

BadenPower 20. Aug 2015 14:06

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;

BUG 20. Aug 2015 14:57

AW: Problem bei SetLength()
 
Zitat:

Zitat von BadenPower (Beitrag 1312868)
Egal was in "TRXHead.Materials" steht, wirft SetLength() niemals diesen Exceptiontyp.

Man kriegt das vermutlich hin, wenn man die Strings, das Array oder allgemein die Speicherverwaltung kaputt macht :wink:

Wenn man keine besseren Analysewerkzeuge hat, könnte man zum Beispiel versuchen, systematisch Programmbestandteile zwischen den Aufrufen auszukommentieren bis es wieder funktioniert.

the3dcloser 20. Aug 2015 16:53

AW: Problem bei SetLength()
 
Zitat:

Zitat von BUG (Beitrag 1312894)
Man kriegt das vermutlich hin, wenn man die Strings, das Array oder allgemein die Speicherverwaltung kaputt macht :wink:

Genau dies war die Lösung!
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:

BUG 20. Aug 2015 17:04

AW: Problem bei SetLength()
 
Zitat:

Zitat von the3dcloser (Beitrag 1312909)
Dafür kommt nun beim Schließen des Programms die SIGSEGV Meldung, aber immerhin wurde dieses Problem gelöst :thumb:

Ehrlich gesagt vermute ich, dass du die Symptome nur verschoben hast, und das Problem von Anfang an woanders lag. Wenn du alle Segfaults los bist, funktioniert es vermutlich auch mit dynamischen Strings :mrgreen:

the3dcloser 23. Aug 2015 20:24

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

EWeiss 23. Aug 2015 21:21

AW: Problem bei SetLength()
 
Delphi-Quellcode:
var
 c:array[1..256] of PAnsiChar;

LoadCPO

BlockRead(f, c[0], 4);
Hier ist schon mal eine Verletzung der Untergrenze.
Zitat:

Das Programm (welches zumindest bei mir Lauffähig ist)
Trotz des Fehlers läuft es bei dir?

Kein DPR, DFM..

Ja Lazarus, deshalb bin ich raus.
Vielleicht hilft dir dieser Fehler schon mal.

gruss

the3dcloser 23. Aug 2015 21:45

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.

p80286 23. Aug 2015 22:24

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

EWeiss 23. Aug 2015 22:27

AW: Problem bei SetLength()
 
Zitat:

Ja, bei mir lief das davor ohne Probleme, jedoch kommt der Fehler nach dem Ausbessern immer noch.
Es hat auch mit dem SetLength Problem nichts zu tun sondern ist ein anderes.

Zitat:

Hört sich für mich so an als ob Du keine Bereichsüberprüfung eingestellt hättest. Ich würde es mal mit versuchen.
Und das geht mit der IDE von Lazarus?

gruss

the3dcloser 24. Aug 2015 09:13

AW: Problem bei SetLength()
 
Zitat:

Zitat von p80286
Hört sich für mich so an als ob Du keine Bereichsüberprüfung eingestellt hättest

Dieses Wort höre ich bedauerlicherweise zum ersten Mal.
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 15:00 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