Kezdőoldal » Számítástechnika » Programozás » FPC/Lazarus-ban random SIGSEGV...

FPC/Lazarus-ban random SIGSEGV errorokat kapok a class-jaimra. Pedig jól néznek ki a Complier se szól, csak amikor futnia kéne akkor meghal. Mi lehet a probléma?

Figyelt kérdés

példának okáért itt is van egy egszerűbb:


type Tsettings=class

values:array of array[0..2] of string;

loaded:boolean;

function get(mit:string):string;

function isSet(mit:string):boolean;

constructor load(filepath:string);

end;


function Tsettings.get(mit:string):string;

var i: word;

fund:boolean;

begin

if loaded then

begin

i:=low(values);

fund:=false;

Repeat

if Upcase(values[i,1]) = Upcase(mit) then fund:=True

else inc(i);

until fund or (i = High(values));


if fund then get:=values[i,2]

else get:='Error: 1';

end else get:='Error: 2';

end;


ha futnia kéne meghal, az "if loaded then" soron, ha kiveszem akkor pedig az "if Upcase(values[i,1]) = Upcase(mit) then fund:=True" soron


de itt egy másik is:


type

particles=class

may,miy:single;

pos:TVector3f; // ez egy típus amiben van egy x egy y és egy z ami single

speed:single;

constructor createfalling(py,ly,pspeed:single);

procedure update;

procedure render;

end;



procedure particles.update;

begin


if pos.y < miy then

begin

pos.x:=Random(512)-256;

pos.z:=Random(512)-256;

pos.y:=may;

end else begin

pos.y:=pos.y-speed;

end;


end;


itt pedig az "if pos.y < miy then" soron hal be.


úgy néz ki mintha az if-eken halna be, de más classok is vannak if-ekkel, és azok mennek, a másik meg hogy a class belső változóitól, de ugyanúgy, mások mennek vele.


a SIGSEGVről ezt találtam:


SIGSEGV = Segmentation Fault = Access Violation under Win


Common causes are;


-> miscalculating array ranges in your loops,

-> accessing objects when not created,

-> or just plain and simple trying to access memory that was not allocated for use.


nincs valakinek bármi építő ötlete, mert ez egy nagyon bosszantó error, amivel nem tudok mit kezdeni :(



2013. jún. 29. 15:11
1 2
 1/11 ejbenjaro ***** válasza:

Az if-ekben vizsgált változók kapnak értéket valamikor a vizsgálat előtt?

Az ide bemásolt kódod nekem nem tűnik hibásnak, nem tudnál inkább egy rövid programot összedobni, ami hozza a hibát?

2013. jún. 29. 16:21
Hasznos számodra ez a válasz?
 2/11 A kérdező kommentje:
természetesen kapnak, mind a két esetben. rövidebb programot nem tudok összedobni, mert nem tudom mitől jön elő, de azért bepróbálkozok, illetve van egy de az 1000+ soros, azt nem kívánom senkinek, hogy bogarássza.
2013. jún. 29. 17:52
 3/11 ejbenjaro ***** válasza:
Esetleg a teljes TSetting osztályt ha közzé tennéd, lehet az is segítene, tehát ha idemásolnád a másik két metódust is, amit a kérdésben nem tettél meg.
2013. jún. 29. 19:16
Hasznos számodra ez a válasz?
 4/11 A kérdező kommentje:

Igenis :)


itt is van(nak):


type:

Tsettings=class

values:array of array[0..2] of string;

loaded:boolean;

function get(mit:string):string;

function isSet(mit:string):boolean;

constructor load(filepath:string);

end;


constructor Tsettings.load(filepath:string);

var line:string;

resetok:boolean;

i:byte;

fv:textfile;

begin

if FileExists(filepath) then

begin

{$i-}

Assign(fv,filepath);

i:=1;

resetok:=false;

// probalkozas a megnyitassal

Repeat

reset(fv);

if ioresult = 0 then resetok:=True

else inc(i);

until (resetok) or (i = 30);

// ha sikerult

if resetok then

begin

i:=1;

While NOT eof(fv) do

Begin

Readln(fv,line);

if NOT(copy(line,1,2) = '//') then

begin

setlength(values,i);

values[i-1,1]:=Upcase(copy(Line,1,pos('=',Line)-1));

values[i-1,2]:=copy(Line, pos('=',Line)+1 , Length(line)-pos('=',Line)+1);

inc(i);

end;

end;

// ha vegzett az olvasassal

closefile(fv);

loaded:=True;

end else loaded:=False;

end else loaded:=False;

{$i+}

end;



function Tsettings.isSet(mit:string):boolean;

var i:longint;

fund:boolean;

begin

if loaded then

begin

i:=low(values);

fund:=false;

Repeat

if Upcase(values[i,1]) = Upcase(mit) then fund:=True

else inc(i);

until fund or (i = High(values));


if fund then isSet:=true

else isSet:=False;

end else isSet:=False;

end;


function Tsettings.get(mit:string):string;

var i: word;

fund:boolean;

begin

if loaded then

begin

i:=low(values);

fund:=false;

Repeat

if Upcase(values[i,1]) = Upcase(mit) then fund:=True

else inc(i);

until fund or (i = High(values));


if fund then get:=values[i,2]

else get:='Error: 1';

end else get:='Error: 2';

end;



és itt hajtom végre:


settings.load(modname + '\scripts\settings.cfg');

InitOpenglwindow(strtoint(settings.get('width')),strtoint(settings.get('Height')),strtoint(settings.get('posx')),strtoint(settings.get('posy')), settings.get('caption'));



és itt a file is ha kell:


// ablak bealitasok

width=600

height=800

posX=10

posY=10

caption=Testmod

// eddig

fov=75

sensitivy=0.1

caption=Testmod


és itt az error, ha a Lazarusból futtatom:


Project main raised exception class 'External: SIGSEGV'

In File 'file_routines.pas' at line 93:

if loaded then


és itt van ha "magába" fut


An unhandled exception occured at $0041D12F :

EAcessViolation: Acess violation

$0041D12F TSETTINGS__GET, line 93 of file_routines.pas

$00401702 INIT, line 46 of main.lpr

$0040182D main, line 66 of main.lpr


ezek a sorok pedig a main.lpr-ből:

46: InitOpenglwindow(strtoint(settings.get('width')),strtoint(settings.get('Height')),strtoint(settings.get('posx')),strtoint(settings.get('posy')), settings.get('caption'));


66: if NOT INIT then halt;


az előbb emlétett init pedig:


function INIT:boolean;

Begin

// mod ellenorzese

if paramcount = 1 then

Begin

if isModExists(ParamStr(1)) then modname:=ParamStr(1)

else modname:='';

end else modname:='';

// mod betoltese

if modname <> '' then

begin

settings.load(modname + '\scripts\settings.cfg');

InitOpenglwindow(strtoint(settings.get('width')),strtoint(settings.get('Height')),strtoint(settings.get('posx')),strtoint(settings.get('posy')), settings.get('caption'));

beep;

//render cuccok

glutDisplayFunc(@Rendertowindow);

glutIdleFunc(@IDLE);

INIT:=True;

end else INIT:=False;

End;


egyszerűen nem jövök rá, hol lehet a hiba

2013. jún. 29. 22:20
 5/11 ejbenjaro ***** válasza:

function INIT:boolean;

Begin

[...]

settings.load(modname + '\scripts\settings.cfg');

[...]

End;


A load ugye a TSettings osztályod konstruktora, a Settings változód gondolom TSettings típusú. Amikor létrehozod az objektumot nem valami ilyesminek kellene lenni a kódnak:

Settings:=TSettings.Load(modname + '\scripts\settings.cfg');

2013. jún. 29. 23:08
Hasznos számodra ez a válasz?
 6/11 A kérdező kommentje:
ez lefordult lefutott, lefagyott Kékhalál újraindult, szóval ezek szerint működik, a kékhalál okát nem fejtettem meg, de ez már a programom többi része, érdekes módon, elolvastam amit találtam a class-okról, de ez elkerülte a figyelmem. mondjuk ez más programoknál működött :) Remélem csak enyi volt a hiba, a többi cuccomon is kipróbálom ezt a megoldást, a ha működik, akkor nagyon köszönöm, ha nem akkor is :)
2013. jún. 29. 23:31
 7/11 A kérdező kommentje:
Ezt el se hiszem, a többi classom is életrekelt! Testvérem, nagyon sokkal tartozom neked, elismerésem, köszönöm meg minden! Már azt hittem a debuggerem bugos, vagy nemtudom. örök hálával tartozom neked! nagyon sokat segítettél köszönöm! ( de érdekes, akkor néhány progin hogy-hogy müködött a sima xy.create ? )
2013. jún. 30. 01:47
 8/11 ejbenjaro ***** válasza:

Örülök, hogy segítettem :). Nem tudom a másik módszerrel miért működött a kód, szerintem nem kellett volna neki.


Ha nem veszed zokon lenne még egy két javaslatom. Mivel a konfigurációs fájlban ilyen név érték párok vannak (width=600), így nem muszáj végig zongoráznod, mint egy szövegfájlt. Használhatsz StringListet ( [link] ), ami kezeli ezt (Names és Value property), vagy talán mégjobb ha a TIniFile ( [link] ) objektumot használod.


Kicsit átírtam a TSettings osztályodat, hogy a TIniFile segítségével lehessen beolvasni a cfg fájlodból adatot, illetve visszaírni is lehessen vele.



A cfg fájl nézzen ki így (lévén az ini fájlok valahogy így épülnek fel):


[Windows settigns]

width=600

height=800

posX=10

posY=10

caption=Testmod

[other]

fov=75

sensitivy=0.1

caption=Testmod



A TSettings osztályod pedig lehet ilyen:


unit Unit1;


{$mode objfpc}{$H+}


interface


uses

Classes, SysUtils, InifFiles;


type

TSettings=Class

private

fWidth: integer;

fHeight: integer;

fPosX: integer;

fPosY: integer;

fCaption: string;

fLoaded: boolean;

fFilePath: string;


procedure SetWidth(aWidth:integer);

procedure SetHeight(aHeight:integer);

procedure SetPosX(aPosX:integer);

procedure SetPosY(aPosY:integer);

procedure SetCaption(aCaption: string);

procedure SetFilePath(aFilePath:string);


public

constructor Create(FilePath:string);

constructor Create(aWidth, aHeight, aPosX,aPosY: integer; aCaption: string);

procedure SaveSettings(FilePath: string);

procedure SaveSettings();


property Width: integer read fWidth write SetWidth;

property Height: integer read fHeight write SetHeight;

property PosX: integer read fPosX write SetPosX;

property PosY: integer read fPosY write SetPosY;

property Caption: string read fCaption write SetCaption;

property FilePath: string read fFilePath write SetFilePath;

property IsLoaded: boolean read fLoaded;

end;


implementation


constructor TSettings.Create(aFilePath:string);

var

ConfigFile: TIniFile;

begin

fLoaded:=False;


if FileExists(aFilePath) then

begin

try

try

ConfigFile:=TIniFile.Create(aFilePath);

except

on EInOutError do writeln('File can not be open!');

end;

fFilePath:=aFilePath;

fWidth:=StrToInt(ConfigFile.ReadString('Windows settings','width','-1'));

fHeight:=StrToInt(ConfigFile.ReadString('Windows settings','height','-1'));

fPosX:=StrToInt(ConfigFile.ReadString('Windows settings','posX','-1'));

fPosY:=StrToInt(ConfigFile.ReadString('Windows settings','posY','-1'));

fCaption:=ConfigFile.ReadString('Windows settings','caption','Default');

fLoaded:=True;

finally

ConfigFile.Free;

end;

end;

end;


constructor TSettings.Create(aWidth, aHeight, aPosX, aPosY: integer; aCaption: string);

begin

fWidth:=aWidth;

fHeight:=aHeight;

fPosX:=aPosX;

fPosY:=aPosY;

fCaption:=aCaption;

fLoaded:=True;

end;


procedure TSettings.SaveSettings(aFilePath:string);

var

ConfigFile: TIniFile;

begin

try

try

ConfigFile:=TIniFile.Create(aFilePath);

except

on EInOutError do writeln('File can not be open!');

end;

ConfigFile.WriteString('Windows settings','width',IntToStr(Width));

ConfigFile.WriteString('Windows settings','height',IntToStr(Height));

ConfigFile.WriteString('Windows settings','posX',IntToStr(PosX));

ConfigFile.WriteString('Windows settings','posY',IntToStr(PosY));

ConfigFile.WriteString('Windows settings','caption',Caption);

finally

ConfigFile.Free;

end;

end;


procedure TSettings.SaveSettings();

begin

SaveSettings(fFilePath);

end;


procedure TSettings.SetWidth(aWidth:integer);

begin

if aWidth in [1..1920] then fWidth:=aWidth

else fWidth:=640;

end;


procedure TSettings.SetHeight(aHeight:integer);

begin

if aHeight in [1..1080] then fHeight:=aHeight

else fHeight:=480;

end;


procedure TSettings.SetPosX(aPosX:integer);

begin

if aPosX in [1..1920] then fPosX:=aPosX

else fPosX:=10;

end;


procedure TSettings.SetPosY(aPosY:integer);

begin

if aPosY in [1..1080] then fPosY:=aPosY

else fPosY:=10;

end;


procedure TSettings.SetCaption(aCaption: string);

begin

fCaption:=aCaption;

end;


procedure TSettings.SetFilePath(aFilePath:string);

begin

fFilePath:=aFilePath;

end;


end.



És amikor a főprogramodból hívod valami ilyesmi lesz:


Settings:=TSettings.Create(modname + '\scripts\settings.cfg');


InitOpenglwindow(Settings.Width, Settings.Height, Settings.PosX, Settings.PosY, Settings.Caption);


A kódot nem teszteltem le, így hibák lehetnek benne!

2013. jún. 30. 20:02
Hasznos számodra ez a válasz?
 9/11 A kérdező kommentje:

Még nem ástam bele magamat nagyon az ini fikeokba, mert nem.is akartam, de ezzel most kedvet csináltál nekem hozzá, látom te már ezt egy sokkal magasabb szinten ûzöd mint én, Mindig jó érzés ha a profiktól tanulhat az ember, és köszönöm, hogy segítettél még plusszban azon felûl amit kértem :). eltartott egy darabig, amíg megfelytettem ezt a kódot, de rájöttem, hogy sokkal hatékonyabb és gyorsabb is mint az enyém, csak egy dolog zaklat, úgy nézem itt elôre meg van adva, hogy mit is tudunk kinyerni a fileból (width, height, fov, stb.) ezzel csak az a problem, hogy ezek a filek jó hosszúak és lesz amit nem lehet elôre tudni belôle (pl. ez közben bele is került: intros=3

intro1=....

intro2=....

intro3=....

ez mondjuk egyszeruen egy tomb lenne de ez csak egy példa) meg lesznek olyan értékek, amiket mondjuk a felhasználó ad meg

( pl. fov ez bemegy string ként, majd visszajön a tárolt érték) azt nem tudom hogy oldjam meg így (mondjuk case of). De mindenesetre köszönöm, hogy rámszántad az idôdet, hogy segíts fejlôdni :)

2013. júl. 1. 01:16
 10/11 ejbenjaro ***** válasza:

:). Közel sem vagyok profi. A kód, amit az előző hozzászólásomban küldtem, több sebből vérzik. Csak hobbi szinten szoktam "bohóckodni" Lazarussal, Free Pascallal, szakmám szerint könyvtáros vagyok. Persze az igaz, hogy nem mostanában kezdtem foglalkozni a Pascal nyelv megismerésével.

Ha írsz egy programot, akkor olyan bemeneti adatod ne legyen, amit előre nem lehet tudni. Ha pedig lehet tudni, akkor már nem ismeretlen, így tehát lehet hozzá változót rendelni és így olyanra csinálhatod az osztályt, amilyenre kell.

2013. júl. 1. 13:28
Hasznos számodra ez a válasz?
1 2

Kapcsolódó kérdések:




Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu

A weboldalon megjelenő anyagok nem minősülnek szerkesztői tartalomnak, előzetes ellenőrzésen nem esnek át, az üzemeltető véleményét nem tükrözik.
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!