seltsame access violation



  • sorry, ich hab mir weder Aufgabenstellung durchgelesen noch bin ich deinen Code durchgegangen, aber

    muhkuhmasta schrieb:

    unsigned char (* wuerfel)[19][19] = new unsigned char [19][19][19];  //repräsentation eines 20*20*20 käsewürfels
    

    😕

    Das ist ein 19x19x19 Wuerfel, kein 20x20x20



  • hm... gut 🤡 naja trotzdem... sinds halt nur 19 (kann man ja leicht ändern). der fehler bleibt.

    merke das ich glaubte es ginge von 0-19 wenn ich 19 schreibe...



  • muhkuhmasta schrieb:

    for(y; y<=19; y++)
        {
            for (x; x<=19;x++)
            {
    

    Nochmal ganz langsam, du musst bei Arrays immer zwischen Dimension und Indexierung unterscheiden. Bei einem n-dimensionalen Array ist es dir nur erlaubt, mit Index 0 bis n-1 zu indexieren. Ansonsten gibts Zugriffsverletzungen und damit UB.

    btw:
    In C++ nimmt man cstdlib und nicht stdlib.h.



  • also wenn ich int foo[5] schreibe darf ich nur auf foo[4] zugreifen... das ist ja sehr selbsterläuternd gestaltet :D... ok... ich werds mal ändern und kucken obs weg geht... morgen...



  • int foo[5] erstellt 5 Integerwerte welche vom Index her von 0 - 4 gehen

    0
    1
    2
    3
    4

    sind wieder die 5 Integerwerten.



  • ich würde hier keine lösung des bwinf mit hinweis darauf, dass es eine lösung fürs bwinf ist hier reinschreiben.
    hab grad deine version mit meiner verglichen, imho hatten wir dieselben ideen 😉

    aber keine bange, ich kopier nix,ist ehrensache 🙂

    if (((double)rand()/((double)RAND_MAX+1))<=(double)p/100)
    

    kann es sein, dass hier wieder ein fehler drinliegt?

    naja egal, ist spät, und ichs teig da jetzt nicht hinter...
    ps: mein prog rechnet jetzt schon seit ner halben stunde,ich hoffe aber, dass man mit einer million durchläufe endlich gute statistische werte erreicht-.-



  • wieso denn? rand() liefert werte bis zu rand_max und wenn ich das teile bekomme ich eine zahl zwischen null und eins und wenn die kleiner oder gleich der angegeben wahrscheinlichkeit ist wird das halt gefüllt...

    nachdem ich das array größer gemacht hab gehts prima. wieso braucht deins denn so ewig? ich bin der meinung schon mit 1000 durchläufen bekommt man ausgezeichnete ergebnisse (sie unterscheiden sich praktisch nicht von 100 durchläufen, aber...)

    ich bastelle grade an so einer tollen commandline version damit ich das ganze in ein batchfile einbinden kann, aber irgendwie liest der die commandozeilenargumente noch nicht richtig... mal sehn ob ich das noch hinbekomme



  • ahh... jetzt geht es.

    kann es sein das du vergessen hast die bereits durchsuchten quader zu markieren? mein programm braucht für 1000000 durchläufe weniger als eine minute (für einen prozentssatz versteht sich)

    aber seltsamer weise ist (anscheinend) immer einer durchlässig... ich muss irgendwo müll machen mit der durchlässigkeitsvariablen... ich find den fehler schon noch 🙂



  • [edit] verdammt doppelt gepostet. löscht das hier mal

    ahh... jetzt geht es.

    kann es sein das du vergessen hast die bereits durchsuchten quader zu markieren? mein programm braucht für 1000000 durchläufe weniger als eine minute (für einen prozentssatz versteht sich)

    aber seltsamer weise ist (anscheinend) immer einer durchlässig... ich muss irgendwo müll machen mit der durchlässigkeitsvariablen... ich find den fehler schon noch 🙂



  • ja, lag an ner schleife-.-,atm brauchen 1000 durchläufe ca 3 sekunden, werd das aber nicht emhr weiter optimieren, für geschwindigkeit gibts ja keine punkte^^
    btw: wie kommen denn bei dir die werte aus?
    hab ingesamt mal 33k durchläufe für verschiedene chancen machen lassen,und das wertbild war dumm, bis 60% fidnet er immer einen wert, zwischen 61 und 75 ist es variabel(mit stark absteigender tendenz) und ab 75 findet er nie einen weg

    hier mal mein code, dann kannste auch vergleichen 🙂

    bool existWay(Cube& cube,int x,int y,int z){
    	//zuerst testen wir, ob dieses feld überhaupt noch im würfel enthalten ist
    	//wenn nicht, kann uns dieses feld auch nicht zum Ziel führen
    	if(x<0||x>19||y<0||y>19||z<0||z>19)return false;
    	//testen ob dieses feld überhaupt frei ist, wenn nicht:abbruch(0=frei)
    	//ist es frei, wird getestet, ob das feld ein unteres randfeld ist,
    	//wenn ja, dann haben wir einen weg gefunden
    	if(cube[x][y][z]==1)return false;
    	if(z==19) return true;
    
    	//das feld ist frei, und kein randfeld,nun müssen wir die funktion
    	//rekursiv erneut aufrufen, um uns weiterzuhangeln
    	//um ein im kreis drehen zu vermeiden, setzen wir dieses feld aber wieder auf 1
    	cube[x][y][z]=1;
    	//nun testen wir alle 6 felder welche eine seite mit dem feld 
    	//welches wir grad testen gemeinsam haben
    	return (existWay(cube,x+1,y,z)||existWay(cube,x-1,y,z)||
    			existWay(cube,x,y+1,z)||existWay(cube,x,y-1,z)||
    			existWay(cube,x,y,z+1)||existWay(cube,x,y,z-1));
    
    }
    bool existWay(Cube& cube){
    	bool found=false;
    	int x=0;
            //wir gehen jedes feld der oberen ebene durch, und berechnen für das feld ob es einen weg gibt, wenn ja->schleife abbrechen, wert zurückgeben
    	while(found==false&&x<20){
    		int y=0;
    		while(found==false&&y<20){
    			found=existWay(cube,x,y,0);
    			++y;
    		}
    		++x;
    	}
    	return found;
    }
    


  • meine werte sind ganz ähnlich (auch wenn ich noch nicht alles mal durchgespielt hab sondern noch mit dem program rumteste) ich kann mich auf jeden fall erinnern das bei 70% käse noch 25% durchlässig waren... aber ich mach mal noch ein paar ordentliche durchläufe wenn ich geklärt hab warum er bei 100% käse immer genau 1 durchlässigen findet... lol



  • mal ne frage: du hast da ja ne verschachtelte schleife, die immer die komplette ebene testet,und rekursiv für jede ebene aufgerufen wird, sollte das nicht ein falsches verhalten hervorrufen? dh sollte es dann nicht möglich sein, dass zwar in der ebene ein loch ist, in der ebene darüber aber keine weiterführung existiert(ergo einfach ein loch im käse welches sich nach unten verlängert), und dein programm fälschlicherweise durchlässig zurückgibt?



  • du meinst das es in ebene z(1) kein loch findet und dann in ebene z(2) weitersucht? eigentlich nicht, die einzige möglichkeit in die ebene zu wechseln ist

    //hier
    if (z<19)
     if (wuerfel[x2][y2][z+1]==0)
      if (pourwater(wuerfel,x2,y2,z+1))
       return true;
    
    //oder hier
    
    if (z>0)
     if (wuerfel[x2][y2][z-1]==0)
      if (pourwater(wuerfel,x2,y2,z-1))
       return true;
    

    sonst sucht er nur x und y koordinaten ab



  • ich rede von so einem fall:

    legende: 0=frei 1=voll
    10111111
    10111101
    11111101
    

    er würde bei dir durch die schleife in die rechte freie spalte gehen, und am ende durchlässig anzeigen.

    erklärung:
    er fängt oben links an:
    das erste feld ist nicht frei, er spirngt zum 2. feld->frei.
    er ruft sich für alle angrenzenden felder selbst auf, und springt somit einen nach unten.
    in der 2. zeile sit er nun in feld 2, er prüft->frei, aber alle angrenzenden felder sind voll, die schleife geht weiter nach rechts->voll->voll->voll->voll->frei->selbstaufruf->nach unten springen->ziel.



  • hm... r i c h t i g... verdammt... das wird fix behoben...



  • poste dann die neuen werte 🙂



  • ich bin mir jetzt nicht sicher ob es das behoben hat aber

    bool pourwater(unsigned char(* wuerfel)[20][20], unsigned char x, unsigned char y, unsigned char z)
    {
    if (z==18) 
    {
    if(wuerfel[x][y][z+1]==0) // wenn wir in den vorletzten ebene sind und der quader drunter leer, die sache beenden
    {return true;}
    }
    	for(unsigned char y2=y; y2<=19; y2++)
    	{
    		for (unsigned char x2=x; x2<=19;x2++)
    		{
    			if (wuerfel[x2][y2][z]==0)
    			{
    
    				wuerfel[x2][y2][z]=3; // diesen quader als durchsucht merken um zirkel zu vermeiden
    				if (z<19)
    				if (wuerfel[x2][y2][z+1]==0)
    				    if (pourwater(wuerfel,x2,y2,z+1))
    						return true;
    
    				if (x2<19)
    				if (wuerfel[x2+1][y2][z]==0)
    					if (pourwater(wuerfel,x2+1,y2,z))
    						return true;
    				if (y2>0)
    				if (wuerfel[x2][y2-1][z]==0)
    					if (pourwater(wuerfel,x2,y2-1,z))
    						return true;
    				if (x2>0)
    				if (wuerfel[x2-1][y2][z]==0)
    					if (pourwater(wuerfel,x2-1,y2,z))
    						return true;
    				if (y2<19)
    				if (wuerfel[x2][y2+1][z]==0)
    					if (pourwater(wuerfel,x2,y2+1,z))
    						return true;
    				if (z>0)
    				if (wuerfel[x2][y2][z-1]==0)
    					if (pourwater(wuerfel,x2,y2,z-1))
    						return true;
    
    			} // end if
    			if (z!=0) break;
    		} //end x schleifel
    		if (z!=0) break;
     } //end y schleife
    return false;
    }
    

    so schauts jetzt aus. die breaks müssten es daran hindern weiterzusuchen wenn es sich nicht in der obersten ebene befindet. findet es einen durchgang kommt es ja gar nicht so weit... ich hab mal einen probelauf mit 70% gemacht und es kamen bei 1000 würfeln 13,6% raus (wasserdurchlässig). aber ich mach mal nen neuen thread in "rund um die programmierung" auf, denn das hier hat absolut nichts mit access violations zu tun.


Anmelden zum Antworten