don't click here

Segmentation Fault (Core Dumped) Error?

Discussion in 'Technical Discussion' started by Alriightyman, Sep 24, 2012.

  1. Alriightyman

    Alriightyman

    I am back... from the dead! Tech Member
    357
    11
    18
    Somewhere in hot, death Florida
    0101001101101111011011100110100101100011 00000010: 0101001100000011 01000101011001000110100101110100011010010110111101101110
    So I am working on a college assignment, and the professor uses a Linux based system to run our code. So, I installed Ubuntu on a VM and setup codeblocks.

    The following code runs perfectly on Visual Studio 2010 on my Host Windows 7, but I get a Segmentation Fault (Core Dumped) error when it runs. I've never seen this error before and even after looking o Google I still can't seem to find the problem.

    Anyone see something I do not?

    NOTE: If more code is required let me know. Also, FYI the second constructor is the only one that is "called" upon creation.

    Code (Text):
    1.  
    2. #include "Maze.h"
    3. #include "Position.h"
    4. #include "DStackT.h"
    5. #include <iostream>
    6. #include <cassert>
    7.  
    8. using namespace std;
    9.  
    10. // FILL IN THE MISSING CODE
    11.  
    12. // Hint Question. For stack: what is the longest possible path in a maze?
    13. Maze::Maze()
    14. {
    15.     size = MAZEMAX;
    16.     // allocate memory for the first pointer
    17.     M = new state*[size];
    18.     // allocate memory for each pointer
    19.     for (int I = 0; I < size; ++I)
    20.         M[I] = new state[size];
    21.     // set the entire maze to a wall
    22.     for(int I = 1; I < size; I++) // row
    23.     {
    24.         for (int j = 1; j < size; j ++) // column
    25.         {
    26.             Position p(I,j);    // create a Position object
    27.             setState(p,WALL);   // set the sate at the current position as a Wall
    28.         }
    29.     }
    30.     // set start position to upper left corner
    31.     start = Position(1,1);
    32.     // set exit position to the bottom right corner
    33.     exit = Position(size,size);
    34.  
    35. }
    36. // constructor with a parameter that tells the maze how large it is.
    37. // max is used as height and width
    38. Maze::Maze(int max)
    39. {
    40.     size = max; // set the max size
    41.     // allocate memory for the first pointer
    42.     M = new state*[size];
    43.     // allocate memory for each pointer
    44.     for (int I = 0; I < size; ++I)
    45.         M[I] = new state[size];
    46.     // set the entire maze to a wall
    47.     for(int I = 1; I < size; I++) // row
    48.     {
    49.         for (int j = 1; j < size; j ++) // column
    50.         {
    51.             Position p(I,j);    // create a Position object
    52.             setState(p,WALL);   // set the sate at the current position as a Wall
    53.         }
    54.     }
    55.     // set start position to upper left corner
    56.     start = Position(1,1);
    57.     // set exit position to the bottom right corner
    58.     exit = Position(size,size);
    59. }
    60.  
    61. // an unused constructor
    62. Maze::Maze(Position s, Position e, int n)
    63. {
    64.     size = n; // set the max size
    65.     // allocate memory for the first pointer
    66.     M = new state*[size];
    67.     // allocate memory for each pointer
    68.     for (int I = 0; I < size; ++I)
    69.         M[I] = new state[size];
    70.     // set the entire maze to a wall
    71.     for(int I = 1; I < size; I++) // row
    72.     {
    73.         for (int j = 1; j < size; j ++) // column
    74.         {
    75.             Position p(I,j);    // create a Position object
    76.             setState(p,WALL);   // set the sate at the current position as a Wall
    77.         }
    78.     }
    79.     // set start position
    80.     start = s;
    81.     // set exit position
    82.     exit = e;
    83.  
    84. }
    85.  
    86. // gets the state of a position
    87. state  Maze::getState(const Position &P) const
    88. {
    89.    return M[P.getRow()][P.getCol()];
    90. }
    91. // displays the maze on screen
    92. void Maze::display(ostream &out) const
    93. {
    94.    out << '\n';
    95.    // loop through each position in the maze
    96.    for (int I=0; I < size;I++) {
    97.     for (int j=0; j < size; j++)
    98.      if (Position(I,j) == start) // if this is the start position
    99.         cout << 's';            // put a s
    100.         else if (Position(I,j) == exit) // if this is the exit then
    101.         cout << 'e';                    // put an e
    102.      else if (M[I][j] == WALL)          // if it is a wall
    103.         out << '*';                     // put a *
    104.         else                            // otherwise
    105.         out << ' ';                     // put a space
    106.     out << '\n';
    107.    }
    108.    out << '\n';
    109. }
    110. // set the state of the position in maze
    111. void Maze::setState(const Position &P, state s)
    112. {
    113.    int I = P.getRow();      // get the row of the current position
    114.    int j = P.getCol();      // get the column of the current position
    115.    // make sure the user didn't put in values that are out of range
    116.    assert(1 <= I && I <= size && 1 <= j && j <= size);
    117.    // set state
    118.    M[I][j] = s;
    119. }
    120. // finds the path to the exit of the maze
    121. bool Maze::findExit()
    122. {
    123.     Position current;   // current position of the mouse
    124.     Position next;      // position to look at
    125.     int currentState;
    126.     // get beginning position
    127.     path.push(start);
    128.     current  = path.top();
    129.     // loop until at the exit
    130.     while (current.getCol() != exit.getCol() || current.getRow() != exit.getRow())
    131.     {
    132.         // loop through all the directions
    133.         for (int I = 0; I < NONE; I++)
    134.         {
    135.             // get the next state
    136.             currentState = getState(current.Neighbor((const direction&)I));
    137.  
    138.             switch(currentState)
    139.             {
    140.             case WALL:  // if it's a wall
    141.                 // check to see if the stack is empty
    142.                 if (path.empty())
    143.                     return false; // if it is, then there was no exit
    144.                 break;  // leave
    145.             case VISITED: // if we have already been there...
    146.                 // first, make sure there are no open spots around
    147.                 if((getState(current.Neighbor(UP)) != OPEN) &&
    148.                     (getState(current.Neighbor(LEFT)) != OPEN) &&
    149.                     (getState(current.Neighbor(DOWN)) != OPEN) &&
    150.                     (getState(current.Neighbor(RIGHT)) != OPEN))
    151.                 {
    152.                     // go back a space
    153.                     path.pop();
    154.                     M[current.getRow()][current.getCol()] = VISITED;
    155.                     // check to see if the stack is empty
    156.                     if (path.empty())
    157.                         return false; // if it is, then there was no exit
    158.                     current = path.top(); // get the new position
    159.                     I = NONE;           // reset "for loop"
    160.                 }
    161.                 break;
    162.  
    163.             case OPEN:
    164.                 // set position to VISITED
    165.                 M[current.getRow()][current.getCol()] = VISITED;
    166.                 // add position to the stack
    167.                 path.push(current.Neighbor((const direction&)I));
    168.                 // set current position to new position
    169.                 current = path.top();
    170.                 // check if this position is the exit
    171.                 if(current == exit)
    172.                     return true;    // exit was found
    173.                 I = NONE;           // reset "for loop"
    174.                 break;
    175.             } //switch
    176.  
    177.  
    178.         } // for loop
    179.  
    180.     }// while loop
    181.  
    182.     // NOTE: should never actually get here
    183.     return false;   // no exit
    184. }
    185.  
    186. void Maze::printPath()
    187. {
    188.    Position P;      // create a position object
    189.    Stack<Position> T(size*size); // create a Stack of Position
    190.    // loop until the path stack is empty,
    191.    // copy the path stack
    192.    while (!path.empty()) {
    193.     T.push(path.top());
    194.     path.pop();
    195.    }
    196.    while (!T.empty()) {
    197.     cout << T.top() << '\n';
    198.     T.pop();
    199.    }
    200. }
    201.  
    202. void Maze::initialize() // Assumes size already set
    203. {
    204.    int I, j;
    205.    cout << "All position indices k must satisfy 1 <= k < = " << (size-1) << '\n';
    206.    cout << "Enter the start position:\n";
    207.    cin >> start;
    208.    cout << "Enter the exit position:\n";
    209.    cin >> exit;
    210.    cout << "Please enter column indices for each row\n";
    211.  
    212.    for (I = 1; I < size-1; I++) {
    213.     cout << "row " << I << ": ";
    214.     cin >> j;
    215.     while (j > 0){
    216.      M[I][j] = OPEN;
    217.      cin >> j;
    218.     };
    219.    }
    220.    if (getState(start) != OPEN) {
    221.     cout << "start position must be open; will fix that now\n";
    222.     M[start.getRow()][start.getCol()] = OPEN;
    223.    }
    224.    if (getState(exit) != OPEN)
    225.     cout << "Boy, are you mean, setting the exit in the wall.  Poor Remy!\n";
    226.    cout << "Maze entry complete\n";
    227. }
    228.  
    229.  
     
  2. Andlabs

    Andlabs

    「いっきまーす」 Wiki Sysop
    2,175
    1
    0
    Writing my own MD/Genesis sound driver :D
    Segmentation fault usually means you wrote to memory outside the bounds of an array. If you use a debugger (such as the one in Visual Studio), you can find the line where the program crashed, which should hint as to what your issue is.

    Taking a glance at your code, however:
    Code (Text):
    1.     M = new state*[size];
    This shouldn't have compiled because the * is just there where it shouldn't be. Did you mean
    Code (Text):
    1.     M = new state[size];
    ?
     
  3. Nibble

    Nibble

    Oldbie
    No, it looks like M is a two-dimensional array. That line is perfectly valid code because it's allocating an array of pointers to 'state', then in the next few lines it's iterating through each pointer and allocating an array of 'state' objects, thus forming the 2D array.

    But yeah, the error means that you're writing to memory you shouldn't be writing to, or perhaps dereferencing an invalid pointer. Another way to debug this (besides using a debugger) is to insert print statements to print your indexes. Make sure everything is in bounds.
     
  4. Alriightyman

    Alriightyman

    I am back... from the dead! Tech Member
    357
    11
    18
    Somewhere in hot, death Florida
    0101001101101111011011100110100101100011 00000010: 0101001100000011 01000101011001000110100101110100011010010110111101101110
    M is a double pointer located in the Maze class:

    Code (Text):
    1.  
    2. state **M; // two-dimensional array of state values
    3.  
    I am not sure how else to allocate a multi-dimensional array from a double pointer.

    And unfortunately, that code I posted is the only one I am allowed to modify.

    EDIT: I'll try that, I can't get that debugger to run in codeblocks so I'll try the print method. Thanks Delta.
     
  5. Andlabs

    Andlabs

    「いっきまーす」 Wiki Sysop
    2,175
    1
    0
    Writing my own MD/Genesis sound driver :D
    The new line still isn't valid because the * should be before the type name, not after:
    Code (Text):
    1.     M = new *state[size];
    unless C++ changed its rules...?
     
  6. Nibble

    Nibble

    Oldbie
    Nope. In C++, for a dynamically allocated array of pointers, the asterisk goes after.

    It's in the format of
    Code (Text):
    1. a = new type[elements];
    In this particular case, the type happens to be 'pointer to state' which would be written as 'state *'. Therefore, asterisk goes after. It only goes before if you're dereferencing a pointer, declaring a static array, or declaring a single pointer variable, I.e.
    Code (Text):
    1. mytype *p1, *p2[100], *p3;
     
  7. Alriightyman

    Alriightyman

    I am back... from the dead! Tech Member
    357
    11
    18
    Somewhere in hot, death Florida
    0101001101101111011011100110100101100011 00000010: 0101001100000011 01000101011001000110100101110100011010010110111101101110
    Well, I got it fixed. It was going out of the array bounds. Funny how Visual Studio "fixes" this on it's own. But at least it run under Linux now.
    I learn something new about C++ everyday.

    Thanks for all the help!
     
  8. Nibble

    Nibble

    Oldbie
    No prob. :)

    I don't think Visual Studio was necessarily "fixing" anything. The exact behavior when writing out of bounds of an array is undefined. In practice, it depends on the layout of memory. I'd guess that Microsoft's compiler/runtime laid out memory in such a way that there was valid data immediately before or after the array; perhaps some other variable or what have you. So writing out of bounds would have corrupted some random program data elsewhere.

    You only get an error if you write/dereference outside of the program's allocated area of memory, which isn't always true when going out of array bounds.