Segmentation Fault with vector of vectors

main.cpp
#include <cstdlib>
#include <vector>
#include <iostream>
#include <cstddef>
#include "Cell.h"
#define MAXX 15
#define MAXY 15
using namespace std;
typedef void* Grid;
/*
 * 
 */
Grid makeGrid(int maxX, int maxY)
{
    
    Cell* r;                  // points to first cell of the grid.. for all
                              // purposes this is a pointer to our grid and
                              // will be returned
    Cell* currentCell; 
    int isFirstRun = 1;
    int isLastRun = 0;
    int membershipCount = 0;   // variable to give each cell a special
                               // membership to it's own group
                               // when two cells join they both 
                               // join the group with the lowest membership
                               // integer
    
    r = new Cell(membershipCount++);  // make first cell, we will return this 
                                    // pointer as the start of the maze
    
    
    
    // a vector of vectors, once the cells are double linked to each other
    // there will be no more need for this to hold everything in place
    // and it will go away.
    std::vector<std::vector<Cell> > grid; //make a vector of vectors to store in
    //Cell[maxX][maxY];
    grid[0][0] = *r;                   //put first cell in first spot
                                       
    
    
    
    // populate our vector of vector grid with cell objects that live in the 
    // heap and then double link them in every direction so they stay in place
    //  after all a real maze is navigated cell by cell.
    for (int y = 0; y <= maxY; y++ )
    {   
        for (int x = isFirstRun; x <= maxX; x++)
        {
            
            currentCell = new Cell(membershipCount++);
            if (0 != y) // if we aren't the top row link the node to the north
            {           // then link that row back to us on the south
                currentCell->setNorth(grid[x][y-1]); // link row above here
                grid[x][y-1].setSouth(*currentCell);// link above row back to us               
            }
            
            if (0 != x) // if we aren't the first column link to the west cell
            {           // then link that cell back to us on the east
                currentCell->setWest(grid[x-1][y]); // link cell behind here
                grid[x][y-1].setEast(*currentCell);// link that cell back to us               
            }
        }   
        isFirstRun = 0; // this isn't the first run anymore so we don't need to
                        // leave space for the first already made cell
    }
    
    return r;
}




int main(int argc, char** argv) {

    
    Grid grid;  // make something to point to the maze while we build it

    grid = makeGrid(MAXX, MAXY);  // build the maze 
    //smashWalls(grid);   //step through each node of the maze and randomly
                          // tear down walls except in the case when 
                          // membership is zero
    //printMaze(grid);  // print out the maze node by node
    return 0;
}

Open in new window

Cell.h
#ifndef CELL_H
#define	CELL_H
#include <cstddef>
#include <cstdlib>
#include <iostream>
using namespace std;
class Cell
/*This class represents a single cell in a maze  *
 * They all should be double linked to each other *
 * There is an array of booleans representing walls
 * and four seperate pointers to indicate adjecency*/
{
private:
    bool walls_[4];
    int membership_;
    Cell* north_;
    Cell* south_;
    Cell* east_;
    Cell* west_;
    

public:
    Cell(int membership)
    {
        membership_ = membership;
        walls_[0] = true; // put up four walls
        walls_[1] = true; // I know this is the ugly way to do it
        walls_[2] = true; // but I can't it to work the right way and need
        walls_[3] = true; // to stop wasting time.
        north_ = NULL;
        south_ = NULL;
        east_ = NULL;
        west_ = NULL;
    }  
    void setNorth(const Cell &cell)
    /* Points the northern direction to 
     * the cell in the parameter       */
    {
        *north_ = cell;
#if DEBUG > 2
        cout << north_ << endl;
#endif
    }
    void setSouth(const Cell &cell)
    /* Points the northern direction to 
     * the cell in the parameter       */
    {
        *south_ = cell;
#if DEBUG > 2
        cout << north_ << endl;
#endif

    }
    void setEast(const Cell &cell)
    /* Points the northern direction to 
     * the cell in the parameter       */
    {
        *east_ = cell;
#if DEBUG > 2
        cout << north_ << endl;
#endif

    }
    void setWest(const Cell &cell)
    /* Points the northern direction to 
     * the cell in the parameter       */
    {
        *west_ = cell;
#if DEBUG > 2
        cout << north_ << endl;
#endif

    }
    int combine(int membership)
    /* Combines this cell with the cell
     from the parameters and returns the
     winning membership ID the cells now
     share                              */
    {
#if DEBUG > 2
        cout << "Cell Membership is:   \t" << membership_ << endl;
        cout << "Cell Membership contender:\t" << membership << endl;
#endif

        if (membership < membership_) { membership_ = membership; }
#if DEBUG > 2
        cout << "Cell Membership is now:   \t" << membership_ << endl;
#endif
        return membership_;
    }
};


#endif	/* CELL_H */

Open in new window


from valgrind
==7957== Memcheck, a memory error detector.
==7957== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==7957== Using LibVEX rev 1854, a library for dynamic binary translation.
==7957== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==7957== Using valgrind-3.3.1-Debian, a dynamic binary instrumentation framework.
==7957== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==7957== For more details, rerun with: -v
==7957==
==7957== Conditional jump or move depends on uninitialised value(s)
==7957==    at 0x40162F1: (within /lib/ld-2.11.2.so)
==7957==    by 0x4007BA4: (within /lib/ld-2.11.2.so)
==7957==    by 0x40029DE: (within /lib/ld-2.11.2.so)
==7957==    by 0x4014056: (within /lib/ld-2.11.2.so)
==7957==    by 0x4000C6C: (within /lib/ld-2.11.2.so)
==7957==    by 0x4000856: (within /lib/ld-2.11.2.so)
--7957-- DWARF2 CFI reader: unhandled CFI instruction 0:10
--7957-- Warning: DWARF2 CFI reader: unhandled DW_OP_ opcode 0x55
--7957-- Warning: DWARF2 CFI reader: unhandled DW_OP_ opcode 0x55
==7957==
==7957== Conditional jump or move depends on uninitialised value(s)
==7957==    at 0x400B16F: (within /lib/ld-2.11.2.so)
==7957==    by 0x4003170: (within /lib/ld-2.11.2.so)
==7957==    by 0x4014056: (within /lib/ld-2.11.2.so)
==7957==    by 0x4000C6C: (within /lib/ld-2.11.2.so)
==7957==    by 0x4000856: (within /lib/ld-2.11.2.so)
==7957==
==7957== Conditional jump or move depends on uninitialised value(s)
==7957==    at 0x400AE6A: (within /lib/ld-2.11.2.so)
==7957==    by 0x4003170: (within /lib/ld-2.11.2.so)
==7957==    by 0x4014056: (within /lib/ld-2.11.2.so)
==7957==    by 0x4000C6C: (within /lib/ld-2.11.2.so)
==7957==    by 0x4000856: (within /lib/ld-2.11.2.so)
==7957==
==7957== Conditional jump or move depends on uninitialised value(s)
==7957==    at 0x400B1D4: (within /lib/ld-2.11.2.so)
==7957==    by 0x4003170: (within /lib/ld-2.11.2.so)
==7957==    by 0x4014056: (within /lib/ld-2.11.2.so)
==7957==    by 0x4000C6C: (within /lib/ld-2.11.2.so)
==7957==    by 0x4000856: (within /lib/ld-2.11.2.so)
==7957==
==7957== Conditional jump or move depends on uninitialised value(s)
==7957==    at 0x400A57E: (within /lib/ld-2.11.2.so)
==7957==    by 0x40030A3: (within /lib/ld-2.11.2.so)
==7957==    by 0x4014056: (within /lib/ld-2.11.2.so)
==7957==    by 0x4000C6C: (within /lib/ld-2.11.2.so)
==7957==    by 0x4000856: (within /lib/ld-2.11.2.so)
==7957==
==7957== Conditional jump or move depends on uninitialised value(s)
==7957==    at 0x400A586: (within /lib/ld-2.11.2.so)
==7957==    by 0x40030A3: (within /lib/ld-2.11.2.so)
==7957==    by 0x4014056: (within /lib/ld-2.11.2.so)
==7957==    by 0x4000C6C: (within /lib/ld-2.11.2.so)
==7957==    by 0x4000856: (within /lib/ld-2.11.2.so)
==7957==
==7957== Conditional jump or move depends on uninitialised value(s)
==7957==    at 0x400AE6A: (within /lib/ld-2.11.2.so)
==7957==    by 0x40030A3: (within /lib/ld-2.11.2.so)
==7957==    by 0x4014056: (within /lib/ld-2.11.2.so)
==7957==    by 0x4000C6C: (within /lib/ld-2.11.2.so)
==7957==    by 0x4000856: (within /lib/ld-2.11.2.so)
==7957==
==7957== Invalid read of size 4
==7957==    at 0x8048A02: std::vector<Cell, std::allocator<Cell> >::operator[](unsigned) (in /home/narmic20/maze/maze)
==7957==    by 0x80486EE: makeGrid(int, int) (in /home/narmic20/maze/maze)
==7957==    by 0x80488BE: main (in /home/narmic20/maze/maze)
==7957==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==7957==
==7957== Process terminating with default action of signal 11 (SIGSEGV)
==7957==  Access not within mapped region at address 0x0
==7957==    at 0x8048A02: std::vector<Cell, std::allocator<Cell> >::operator[](unsigned) (in /home/narmic20/maze/maze)
==7957==    by 0x80486EE: makeGrid(int, int) (in /home/narmic20/maze/maze)
==7957==    by 0x80488BE: main (in /home/narmic20/maze/maze)
==7957==
==7957== ERROR SUMMARY: 19 errors from 8 contexts (suppressed: 0 from 0)
==7957== malloc/free: in use at exit: 24 bytes in 1 blocks.
==7957== malloc/free: 1 allocs, 0 frees, 24 bytes allocated.
==7957== For counts of detected errors, rerun with: -v
==7957== searching for pointers to 1 not-freed blocks.
==7957== checked 95,968 bytes.
==7957==
==7957== LEAK SUMMARY:
==7957==    definitely lost: 0 bytes in 0 blocks.
==7957==      possibly lost: 0 bytes in 0 blocks.
==7957==    still reachable: 24 bytes in 1 blocks.
==7957==         suppressed: 0 bytes in 0 blocks.
==7957== Rerun with --leak-check=full to see details of leaked memory.
Segmentation fault

Open in new window

GPicassoAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Hamed ZaghaghiProgrammerCommented:
Hi,
You don't use vector properly and it's the problem.
using this line of code:
std::vector<std::vector<Cell> > grid;
you only define a vector of vector of Cell with no space for items. You should push_back items in grid, also you can use constructor or resize method to change the size of vector from its default(0).

e.g.
std::vector<int> g;
g.push_back(0);
g.push_back(1);
g.push_back(2);
g.push_back(3);

Open in new window


is equal to:
std::vector<int> g(4);
for (int i=0; i<4; i++)
    g[i] = i;

Open in new window

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
C++

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.