Roguelike dungeon generator segfaults, compiles fine

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • kidko
    New Member
    • Apr 2007
    • 17

    Roguelike dungeon generator segfaults, compiles fine

    Hi, I'm in the process of writing a roguelike (ex Nethack). It's not big, but should still be playable. I've gotten to level generation, and am basically just 'carving' the rooms out of a blank slate.

    The entire floor starts off as an array of rock (0x00), with passable rooms/hallways being open space (0x01). Basically, mapgen::createM ap() generates a room and hallway MAXROOMS times. It makes sure that nothing overlaps or goes out of the bounds of the array (which is MAXX by MAXY). It compiles fine, but as soon as I call createMap, it spouts the error "Segmentati on fault (core dumped)". Does anybody have any ideas as to what is going wrong?

    I'm compiling using g++ 1.4.2 (Ubuntu).

    Code:
    #ifndef MAPGEN_H
    #define MAPGEN_H
    
    #include "dice.h"
    // Has the header with rand() in it... just the library version
    
    namespace mapgen {
    
    	const int MAXX = 80; // Change to change map sizes
    	const int MAXY = 22; // " "
    	const int MAXROOMS = 6;
    	const int MAXROOMX = 5;
    	const int MAXROOMY = 5;
    	const int MAXHALLLENGTH = 10;
    
    	int map[MAXX][MAXY]; // Initialize map
    	
    	int makeHall(int atx, int aty, int dir) {
    		// Directions:
    		//    1
    		// 2     0
    		//    3
    
    		int length = (rand() % MAXHALLLENGTH) + 1;
    		
    
    		bool clean = true;
    		// Checks for size
    		if ((length + atx) > MAXX || (atx - length) < 0 || (aty - length) < 0 || (length + aty) > MAXY) {
    			clean = false;
    		}
    
    		if (clean) {
    	
    			if (dir == 0) {
    				// East
    				for (int i = atx; i <= length; i++) {
    					map[i][aty] = 0x01;
    				}
    			} else if (dir == 1) {
    				// North
    				for (int i = aty; i <= length; i--) {
    					map[atx][i] = 0x01;
    				}
    			} else if (dir == 2) {
    				// West
    				for (int i = atx; i <= length; i--) {
    					map[i][aty] = 0x01;
    				}
    			} else {
    				// South
    				for (int i = aty; i <= length; i++) {
    					map[atx][i] = 0x01;
    				}
    			}
    		}	
    	
    	return 0;	
    
    	}
    	
    	void makeRoom() {
    		int xa, xb, ya, yb; // Rectangle Coords:
            /* (xa, ya) +---------+
     *                  |         |
     *                  |         |
     *                  +---------+ (xb, yb)
     		*/
    		int height, width; // For calcs...
    		
    		height = (rand() % MAXROOMY) + 1;
    		width = (rand() % MAXROOMX) + 1;
    		
    		xa = rand() % MAXX;
    		ya = rand() % MAXY;
    		xb = xa + width;
    		yb = ya + height;
    
    		bool clean = true;
    
    		// Check to make sure area of room is clear
    		if (map[xa][ya] != 0x00 || map[xb][yb] != 0x00) {
    			clean = false;
    		}
    		// Check to make sure it's in the grid...
    		if (xb > MAXX || yb > MAXY) {
    			clean = false;
    		}
    		
    		if (clean) {
    
    			for (int i = xa; i <= xb; i++) {
    				for (int j = ya; j <= yb; j++) {
    					map[i][j] = 0x01; // Floor ('.')
    				}
    			}
    	
    			int hx;
    			int hy;
    
    			int wall = (rand() % 4);
    			if (wall == 0) {
    				// East
    				hx = xb;
    				hy = (ya + (rand() % (yb - 1)) + 1);
    			} else if (wall == 1) {
    				// North
    				hx = (xa + (rand() % (xb - 1)) + 1);
    				hy = ya;
    			} else if (wall == 2) {
    				// West
    				hx = xa;
    				hy = (ya + (rand() % (yb - 1)) + 1);
    			} else {
    				// South
    				hx = (xa + (rand() % (xb - 1)) + 1);
    				hy = yb;
    			}
    
    			makeHall(hx,hy,wall);
    		}
    	}
    
    
    	void createMap() {
                    for (int i = 0; i < MAXX; i++) {
                            for (int j = 0; j < MAXY; i++) {
                                    map[i][j] = 0x00;
                            }
                    }
                    for (int i = 0; i <= MAXROOMS; i++) {
                            makeRoom();
                    }
            }
    
    }
    
    #endif
  • RRick
    Recognized Expert Contributor
    • Feb 2007
    • 463

    #2
    Seg faults usually mean you are trying to access an illegal address like 0x0, or 0x01 or something like that.

    Instead of trying to solve the problem by looking at the code, let the debugger (i.e. gdb or ddd) or memory checker (i.e. valgrind) tell you what is happening.

    The debugger is especially good at stopping at seg fault conditions and then you can inspect the vlaues in the variables right there. To turn on the debugging, add "-g -O0" flags to your compilation.

    Comment

    • kidko
      New Member
      • Apr 2007
      • 17

      #3
      GDB helped a lot. It located the segfault: mapgen.h: 127 (newline) map[i][j] = 0x00;

      So, is my code trying to reference the memory at 0x00? And if it is, I should be using decimal for symbols instead of hex?

      Originally posted by RRick
      Seg faults usually mean you are trying to access an illegal address like 0x0, or 0x01 or something like that.

      Instead of trying to solve the problem by looking at the code, let the debugger (i.e. gdb or ddd) or memory checker (i.e. valgrind) tell you what is happening.

      The debugger is especially good at stopping at seg fault conditions and then you can inspect the vlaues in the variables right there. To turn on the debugging, add "-g -O0" flags to your compilation.

      Comment

      • kidko
        New Member
        • Apr 2007
        • 17

        #4
        Sorry to double post, but it won't let me edit any more.

        I recompiled after changing all 0x00s to 0s, 0x01s to 1s, etc., and again included -g -O0 in my g++ flags. When I ran it through gdb, it isolated the segfault at the same point. What's wrong with this code? (Snipped to what I think plays a part):
        [code="cpp"]
        namespace mapgen {

        const int MAXX = 80; // Change to change map sizes
        const int MAXY = 22; // " "

        int map[MAXX][MAXY]; // Initialize map

        void createMap() {
        for (int i = 0; i < MAXX; i++) {
        for (int j = 0; j < MAXY; i++) {
        map[i][j] = 0; // SEGFAULT HERE
        }
        }
        for (int i = 0; i <= MAXROOMS; i++) {
        makeRoom();
        }
        }

        }[/code]

        Comment

        • weaknessforcats
          Recognized Expert Expert
          • Mar 2007
          • 9214

          #5
          Originally posted by kidko
          namespace mapgen {

          const int MAXX = 80; // Change to change map sizes
          const int MAXY = 22; // " "

          int map[MAXX][MAXY]; // Initialize map

          void createMap() {
          for (int i = 0; i < MAXX; i++) {
          for (int j = 0; j < MAXY; i++) { <<<<Maybe j++ >????
          map[i][j] = 0; // SEGFAULT HERE
          }
          }
          for (int i = 0; i <= MAXROOMS; i++) {
          makeRoom();
          }
          }

          }
          It looks like you have an error in your loop.

          Comment

          • RRick
            Recognized Expert Contributor
            • Feb 2007
            • 463

            #6
            I can't see what is causing the seg fault in that part of the code. From the debugger, take a look at the address of map at different places (like main and you subroutine). If that has been corrupted (somehow), then it could causing the problems. Also, try setting a break point just before the crash and then step through the code. This might give you an idea of what is happening.

            Corrupted addresses could be from mixing different versions of source code during the linking stage. If the corruption happens at runtime, then valgrind is the way to go. Be sure to use the memcheck option. In fact, I would try valgrind anyway. Its a second opinion and might point out the problem.

            Comment

            • kidko
              New Member
              • Apr 2007
              • 17

              #7
              Originally posted by weaknessforcats
              It looks like you have an error in your loop.
              I can't believe I didn't catch that. It works fine now.

              Thank you!

              Comment

              • RRick
                Recognized Expert Contributor
                • Feb 2007
                • 463

                #8
                So enlighten us (actually me) with what it was. I still don't see it.

                Comment

                • Studlyami
                  Recognized Expert Contributor
                  • Sep 2007
                  • 464

                  #9
                  in his 2nd loop he used a i++ instead of a j++ (look at weakness post, he put a comment next to the line that caused the problem. I over-looked it too, untill weakness put up the comment.

                  Comment

                  Working...