Page 1 of 1

[PROG] Trap bij proefexamen

Posted: Wed Jan 17, 2007 3:01 pm
by Heatryn
Hallo, was even als voorbereiding op het practicum van programmeren m'n proefexamen aan het maken. Nu, ik zit met een lastige trap (duh!) die ik niet echt kan vinden. Ik maak eerst een boom aan met een 1ste naam erin. Dat gaat goed. Dan voeg ik daar een kind aan toen, ook nog in orde. Nu, als ik dan nog een broer wil geven aan dit laatste kind, want erop neerkomt gewoon nog een kind toe te voegen aan die eerste persoon, loopt het mis. Ik kan perfect een kind aan dat laatste kind geven. Maar vanaf ik iemand twee kinderen wens te geven loopt het mis. Nu, hier m'n code:

Code: Select all

(*
	Author: Joël Craenhals
	Date Created: 12/12/2006
*)

MODULE Proefexamen;

	IMPORT
		OutExt;

	TYPE
		String* = ARRAY 50 OF CHAR;
		Stamboom* = POINTER TO StamboomBeschrijving;
		StamboomBeschrijving* =
			RECORD
				naam*: String;
				echtgenoot*: String;
				kinderen*: ARRAY 50 OF Stamboom;
				overleden*, getrouwd*: BOOLEAN;
			END;
	
	PROCEDURE Zoeken* (stamboom: Stamboom; naam: String; VAR gevonden: BOOLEAN): Stamboom;
	
		VAR
			i: INTEGER;
			
	BEGIN
		gevonden := FALSE;
		IF (stamboom^.naam = naam) THEN
			gevonden := TRUE;
			RETURN stamboom;
		ELSIF (stamboom^.echtgenoot = naam) THEN
			gevonden := TRUE;
			RETURN stamboom;
		ELSIF (stamboom^.kinderen[0] # NIL) THEN
			FOR i:=0 TO 49 DO
				stamboom := Zoeken(stamboom^.kinderen[i], naam, gevonden);
				IF (gevonden = TRUE) THEN
					gevonden := TRUE;
					RETURN stamboom;
				END;
			END;
		ELSE
			gevonden := FALSE;
			stamboom := NIL;
			RETURN stamboom;
		END;
	END Zoeken;

	PROCEDURE (stamboom: Stamboom) Toevoegen* (naamKind, naamOuder: String; rootPersoon: String);
	
		VAR
			stamboomOrigineel, tmpPtr: Stamboom;
			i, j: INTEGER;
			gevondenOuder, gevondenKind, gevondenRootPersoon: BOOLEAN;
	
	BEGIN
		stamboomOrigineel := stamboom;
		gevondenOuder := FALSE;
		gevondenKind := FALSE;
		gevondenRootPersoon := FALSE;
		i := 0;
		stamboom := Zoeken(stamboomOrigineel, naamOuder, gevondenOuder);
		IF ((gevondenOuder = TRUE) & (stamboom # NIL)) THEN
			NEW(tmpPtr);
			tmpPtr := Zoeken(stamboom, naamKind, gevondenKind);
			IF ((gevondenKind = FALSE) & (tmpPtr = NIL)) THEN
				FOR j:=0 TO 49 DO
					IF (stamboom^.kinderen[j] # NIL) THEN
						INC(i);
					END;
				END;
				NEW(stamboom^.kinderen[i]);
				stamboom^.kinderen[i]^.naam := naamKind;
				OutExt.String(naamKind);
				OutExt.String(" is toegevoegd als kind van ");
				OutExt.String(naamOuder);
				OutExt.String("!");
				OutExt.Ln;
			ELSE
				OutExt.String(naamKind);
				OutExt.String(" werd reeds toegevoegd als kind van ");
				OutExt.String(naamOuder);
				OutExt.String(" en is bijgevolg niet opnieuw toegevoegd!");
				OutExt.Ln;
			END;
		ELSE
			OutExt.String(naamOuder);
			OutExt.String(" is niet gevonden in de stamboom en bijgevolg kan ");
			OutExt.String(naamKind);
			OutExt.String(" niet toegevoegd worden!");
			OutExt.Ln;
		END;
		stamboom := Zoeken(stamboomOrigineel, rootPersoon, gevondenRootPersoon);
		IF (gevondenRootPersoon = TRUE) THEN
			OutExt.String("Stamboom is terug gezet op de pointer naar de root-persoon, namelijk ");
			OutExt.String(stamboom^.naam);
			OutExt.String("!");
			OutExt.Ln;
		END;
	END Toevoegen;

BEGIN
END Proefexamen.
Uiteraard heb ik ook nog een test bestandje waar ik gewoon iets inlees en daarmee die procedures test. Maar daar staat op zich niets belangrijks in.

Posted: Wed Jan 17, 2007 3:41 pm
by EagleEye812
laat is 1) uwen trap en 2) het stukje van uwen test dat em uitvoert op het moment van de trap zien

Posted: Wed Jan 17, 2007 3:51 pm
by Heatryn
Hier heb ik even mijn test module online gezet. Zoals te zien wordt er niet echt iets gedaan wat tot een trap zou kunnen leiden.

Code: Select all

(*
	Author: Joël Craenhals
	Date Created: 12/12/2006
*)

MODULE Test;

	IMPORT
		In, OutExt, Proefexamen;
		
	VAR
		stamboom: Proefexamen.Stamboom;
		rootPersoon: Proefexamen.String;
		
	PROCEDURE BeginStamboom*;
			
	BEGIN
		In.Open;
		In.String(rootPersoon);
		IF (stamboom = NIL) THEN
			NEW(stamboom);
			stamboom^.naam := rootPersoon;
			OutExt.String("De stamboom werd aangemaakt met als 1ste persoon ");
			OutExt.String(stamboom^.naam);
			OutExt.String("!");
			OutExt.Ln;
		ELSE
			OutExt.String("De stamboom werd niet aangemaakt omdat deze reeds bestaat met als 1ste persoon ");
			OutExt.String(stamboom^.naam);
			OutExt.String("!");
			OutExt.Ln;
		END;	
	END BeginStamboom;
	
	PROCEDURE Toevoegen*;
	
		VAR
			naamKind, naamOuder: Proefexamen.String;
	
	BEGIN
		In.Open;
		In.String(naamKind);
		In.String(naamOuder);
		stamboom^.Toevoegen(naamKind, naamOuder, rootPersoon);
	END Toevoegen;
	
	PROCEDURE Verwijderen*;
	
		VAR
			naamPersoon: Proefexamen.String;
	
	BEGIN
		In.Open;
		In.String(naamPersoon);
		stamboom^.Verwijderen(naamPersoon);
	END Verwijderen;

BEGIN
END Test.
Ik voer uit:

Test.BeginStamboom "Evert"
Test.Toevoegen "Joske" "Evert"
Test.Toevoegen "Dieter" "Joske"
Test.Toevoegen "Kurt" "Joske" (hier krijg ik trap)

Trapcode:

Code: Select all

TRAP access violation in thread Oberon.Loop

Proefexamen.Zoeken  PC = 162
	gevonden = FALSE
	i = 1
	naam = "Kurt"
	stamboom =  00000000H (Proefexamen.StamboomBeschrijving)
Proefexamen.StamboomBeschrijving.Toevoegen  PC = 421
	gevondenKind = FALSE
	gevondenOuder = TRUE
	gevondenRootPersoon = FALSE
	i = 0
	j = 0
	naamKind = "Kurt"
	naamOuder = "Joske"
	rootPersoon = "Evert"
	stamboom =  0142EEA0H Proefexamen.StamboomBeschrijving
	stamboomOrigineel =  0142E760H Proefexamen.StamboomBeschrijving
	tmpPtr =  00986080H Proefexamen.StamboomBeschrijving
Test.Toevoegen  PC = 307
	naamKind = "Kurt"
	naamOuder = "Joske"
Oberon.Call  PC = 5937
	Mod =  0142B6A0H Kernel.ModuleDesc
	P = Test.Toevoegen  PC = 189
	cur =  0098FA20H Windows.Window (Displays.Display)
	f =  0034C040H Desktops.DocViewerDesc (Objects.ObjDesc)
	i = 5
	j = 14
	name = "Toevoegen"
	new = FALSE
	par =  00986060H Oberon.ParRec
	res = 1
TextGadgets0.Call  PC = 16616
	A =  00419CF8H Objects.AttrMsg
	F =  0034AFC0H TextGadgets.FrameDesc (TextGadgets0.FrameDesc)
	R =  00441AB8H Texts.Reader
	S =  00441A18H Texts.Scanner
	ch =  00000000X
	chl = 32767
	cmd = ""
	cw = 32767
	cx = 0
	cy = 0
	dlink =  0034AAA0H Documents.DocumentDesc (Objects.ObjDesc)
	i = 4
	j = 0
	keysum = {1}
	obj =  0034C040H Desktops.DocViewerDesc (Objects.ObjDesc)
	oldcontext =  00000000H (Objects.ObjDesc)
	par =  00986060H Oberon.ParRec
	pos = 308
	res = 1
........
De trapcode is langer maar daaronder staat niets relevant meer om te gebruiken. Volgens mij ligt de fout ergens in die Zoekprocedure. Ergens als ik die recursie ga toepassen...

Posted: Wed Jan 17, 2007 3:59 pm
by EagleEye812
In je zoeken he,

Code: Select all

         FOR i:=0 TO 49 DO
            stamboom := Zoeken(stamboom^.kinderen[i], naam, gevonden);
            IF (gevonden = TRUE) THEN
               gevonden := TRUE;
               RETURN stamboom;
            END;
         END; 
De eerste keer gaat dien ne stamboom vinden, no problem, maar als i=1
dan gaat em "Zoeken" aanroepen met NIL als 1e argument
right?

Want ge loopt zomaar door al uw kinderen, terwijl 1-49 mogelijk NIL zijn!

Zet hiervoor:

Code: Select all

stamboom := Zoeken(stamboom^.kinderen[i], naam, gevonden);
nog een controle op NIL heid van die deelboom

Posted: Wed Jan 17, 2007 4:28 pm
by Heatryn
Wat je zegt klopt ja. Ik begin mijn stamboom met Evert. Dan voeg ik bij Evert Joske toe als eerste kind. Dan voeg ik bij Joske Dieter toe als eerste kind, maar inderdaad, ik wil dan bij Evert een tweede kind gaan toevoegen. Dus eigenlijk moet het dit zijn:

Code: Select all

	PROCEDURE Zoeken* (stamboom: Stamboom; naam: String; VAR gevonden: BOOLEAN): Stamboom;
	
		VAR
			i: INTEGER;
			
	BEGIN
		gevonden := FALSE;
		IF (stamboom^.naam = naam) THEN
			gevonden := TRUE;
			RETURN stamboom;
		ELSIF (stamboom^.echtgenoot = naam) THEN
			gevonden := TRUE;
			RETURN stamboom;
		ELSIF (stamboom^.kinderen[0] # NIL) THEN
			FOR i:=0 TO 49 DO
				IF (stamboom^.kinderen[i] # NIL) THEN
					stamboom := Zoeken(stamboom^.kinderen[i], naam, gevonden);
				END;
				IF (gevonden = TRUE) THEN
					gevonden := TRUE;
					RETURN stamboom;
				END;
			END;
		ELSE
			gevonden := FALSE;
			stamboom := NIL;
			RETURN stamboom;
		END;
	END Zoeken;
Thans, heb het ervoor gezet en blijf die trap krijgen. :?

Posted: Wed Jan 17, 2007 4:43 pm
by EagleEye812
als em nu (in diezelfde lus) op i=0 niks vindt, dan gatem al stampboom gelijk gezet hebben aan NIL, en in de 2e lus (i=1) gaat em aan uwe nieuwe conditie kijken:

Code: Select all

IF (stamboom^.kinderen[i] # NIL
crash! want uwe stamboom is NIL , en ge kunt geen ^ trekke van ne NIL

Posted: Wed Jan 17, 2007 4:56 pm
by Heatryn
Ja, uw redenering klopt, maar hoe los ik dat op?

Re: [PROG] Trap bij proefexamen

Posted: Wed Jan 17, 2007 4:56 pm
by cG`

Code: Select all

	PROCEDURE (stamboom: Stamboom) Toevoegen* (naamKind, naamOuder: String; rootPersoon: String);
	
     ...
		IF ((gevondenOuder = TRUE) & (stamboom # NIL)) THEN
			NEW(tmpPtr);
			tmpPtr := Zoeken(stamboom, naamKind, gevondenKind);
			IF ((gevondenKind = FALSE) & (tmpPtr = NIL)) THEN
				FOR j:=0 TO 49 DO
					IF (stamboom^.kinderen[j] # NIL) THEN
						INC(i);
					END;
				END;
	...
	END Toevoegen;

BEGIN
END Proefexamen.
De Trap gebeurde wanneer ge controleerde of er al iemand bestond met de naam Kurt. Kheb die controle ff weggelaten en de FOR-lus eronder vervangen door een WHILE:

Code: Select all

IF ((gevondenOuder = TRUE) & (stamboom # NIL)) THEN
         gevondenKind := FALSE;
         IF ((gevondenKind = FALSE) & (tmpPtr = NIL)) THEN
         	WHILE ( (i < 49) & (stamboom^.kinderen[i] # NIL) ) DO
             	INC(i);
             END;
            NEW(stamboom^.kinderen[i]);
Die boolean en tmpPtr hebben geen nut in wat ik heb gedaan he, die kunnen dus gwn weg.
Ofwel bekijkte nog is goe hoe ge kunt controleren dat er zo nog geen kind bestaat, heb daar nu nie achter gezocht, of laat die controle weg. Veronderstel anders ff voorlopig dat er geen kinderen zullen toegevoegd worden met dezelfde naam en voeg die extra controle eventueel later nog toe he. Zo zou'k het toch iig doen op het examen, want het zijn dingen die nie echt noodzakelijk zijn maar waar ge veel tijd mee kunt verliezen als het nie wil werken he.

*edit* heb nog wat extra mensen proberen toe te voegen:
ProefTest.BeginStamboom "Evert"
ProefTest.Toevoegen "Joske" "Evert"
ProefTest.Toevoegen "Dieter" "Joske"
ProefTest.Toevoegen "Kurt" "Joske"
ProefTest.Toevoegen "Jef" "Joske"
ProefTest.Toevoegen "Jozef" "Evert"
ProefTest.Toevoegen "Els" "Jef"
Bij de laatste stap krijg'k dus nen trap in de zoekprocedure, wsl door wat EagleEye812 zegt

Posted: Wed Jan 17, 2007 4:57 pm
by EagleEye812
Heatryn wrote:Ja, uw redenering klopt, maar hoe los ik dat op?
Zorgen dat em nooit een ^ kan pakken van een NIL pointer he, da moet ge zelf maar oplossen ;)

Posted: Wed Jan 17, 2007 6:14 pm
by zarry
checkt gewoon altijd op nil als ge ne pointer moe lezen ofzo en zet er nen out bij de ne pointer nil is, da maakt u kans op traps heel klein en het opsporen heel groot.. ook ziet ge dan of u programma werkt of echt werkt