13 Replies - 273 Views - Last Post: 07 February 2012 - 12:53 PM Rate Topic: -----

Topic Sponsor:

#1 Bryston  Icon User is offline

  • D.I.C Head

Reputation: 15
  • View blog
  • Posts: 122
  • Joined: 24-January 12

segmentation fault driving me buggy

Posted 04 February 2012 - 08:20 AM

status :: newbie

I am writing a poker program to get better aquainted with beginner stuff and have encountered a segmentation fault.
Debugging says: STATUS_STACK_BUFFER_OVERRUN encountered.

The problem surface when I tried to add the ability to draw new cards in the program.

Here's how I have it laid out:

After getting the number of users (I have hard coded this in to test and it makes no difference)

dynamically create arrays to hold the players hands
    // create the arrays to hold the players hands
    // first create an array to hold the address to each player
    int** player_array_ptr = new int*[ players ];
    // now create an array for each players hand
    for (int array_player = 0; array_player < players; array_player++){
        player_array_ptr[array_player] = new int[cards_to_deal];
        }



call the dealer function to fill the hands (works perfectly)
the call
    for (int player = 0; player < players; player++){
        dealer(player_array_ptr[player]);
        }



and the function
int dealer(void* deal_player_array){
    // get temporary access to the players hand array
    int* deal_access=(int*)deal_player_array;   
    // declare our variables for this function
    int suit, face, n, this_card, new_card;
    // set up temporary arrays to hold the hands values
    int our_hand_card [5];
    int our_hand_suit [5];
    // loop until the player has 5 cards
     for (int card = 0; card < cards_to_deal; ++card){
         // tell the randomizer to decrement
         n = randomizer(cards_remaining--);
         // get the next available card
         this_card = next_available(n);
         // modulo and divide to get value for face and suit
         face = this_card % 13;
         suit = this_card / 13;
         // stuff these values into the arrays
         our_hand_card[card]=face;
         our_hand_suit[card]=suit;
         // get a unique int representing suit and face
         new_card=((suit*100)+(face));
         // put the cards unique int into the players hand
         deal_access[card]=new_card;
         }
     return(0);
}// end function dealer



now the problem area

call the draw function
    for (int player = 0; player < players; player++){
        draw(player_array_ptr[player]);
        }



and the function itself
int draw(void* draw_player_array){
    // get temporary access to the players hand array
    int* draw_access=(int*)draw_player_array;   
    // declare our variables for this function
    int suit, face, n, this_card, new_card;
    // set up temporary arrays to hold the hands values
    int our_hand_card [5];
    int our_hand_suit [5];
    for (int card = 0; card < 5; card++){
        if (get_choice(card) == 1){ // start if
            // replace a card
            // tell the randomizer to decrement
            n = randomizer(cards_remaining--);
            // get the next available card
            this_card = next_available(n);
            // modulo and divide to get value for face and suit
            face = this_card % 13;
            suit = this_card / 13;
            // stuff these values into the arrays
            our_hand_card[this_card]=face;
            our_hand_suit[this_card]=suit;
            // get a unique int representing suit and face
            new_card=((suit*100)+(face));
            // put the cards unique int into the players hand
            draw_access[card]=new_card;
            }// end if
    }// end for
return(0);
}// end function draw



If I never draw a card there is no problem, so the fault lays somewhere inside the if statement in the draw function I think.

I thought maybe i was passing a bad value through the pointer so I hard set the value of new_card to a known valid value, same problem.
Then I tried changing get_choice so it bypassed all the stuff there and always returned a (1) in case my cin stuff was causing problems.

I put in multiple cout's showing what the values of different variables were at crash time and the results were ambiguous. Sometimes it would crash inside the draw function, sometimes back in main. I am sure that a bad value is being passed through the pointer into the array but can't find it (I am totally new to debugging).

I do delete the dynamically created arrays at the end of the program, but I never get there :)
    //delete the dynamic arrays to avoid a memory leak
    for (int delete_player = 0; delete_player < players; delete_player++)
        delete[] player_array_ptr[ delete_player ];
    delete[] player_array_ptr;



What should I try or where should I look?

Is This A Good Question/Topic? 0
  • +

Replies To: segmentation fault driving me buggy

#2 jimblumberg  Icon User is offline

  • member icon

Reputation: 1892
  • View blog
  • Posts: 5,681
  • Joined: 25-December 09

Re: segmentation fault driving me buggy

Posted 04 February 2012 - 08:25 AM

Run the program through your debugger. When it crashes it will tell you the line where the error was detected and you can also inspect the values the variables had when the program crashed.

Jim
Was This Post Helpful? 0
  • +
  • -

#3 Bryston  Icon User is offline

  • D.I.C Head

Reputation: 15
  • View blog
  • Posts: 122
  • Joined: 24-January 12

Re: segmentation fault driving me buggy

Posted 04 February 2012 - 08:59 AM

Quote

Run the program through your debugger. When it crashes it will tell you the line where the error was detected and you can also inspect the values the variables had when the program crashed.

Jim


I have been trying that, but I am unfamiliar with how the debugger works in enough detail to get a result that I can understand. Unfortunately I only have intermittent and unreliable internet access so it has been a frustrating process, I have been trying to get past this error for 2 days by pounding through the hard copy manuals i have and by trial and error. I'm finally able to get online today for a couple of hours and will be doing as much research as I can on how to move forward.
Was This Post Helpful? 0
  • +
  • -

#4 jimblumberg  Icon User is offline

  • member icon

Reputation: 1892
  • View blog
  • Posts: 5,681
  • Joined: 25-December 09

Re: segmentation fault driving me buggy

Posted 04 February 2012 - 09:11 AM

Without a complete program that demonstrates the problem trying to find a segmentation fault is like trying to find a needle in a haystack. One thing I would suggest is you start using std::vector and std::string to eliminate most of the dynamic memory allocations.

What compiler, IDE and operating system are you using? How to use the debugger depends on which compiler, IDE you are using. Without this information I can not point you to documentation on using your debugger.

Do you have your compiler generating warnings as well as errors? Most compilers do not by default generate warnings, you must change settings, or add compile time switches to enable warning generation. Trying to write reliable programs with just errors is very difficult if not impossible.

Jim

This post has been edited by jimblumberg: 04 February 2012 - 09:13 AM

Was This Post Helpful? 1
  • +
  • -

#5 Karel-Lodewijk  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 438
  • View blog
  • Posts: 849
  • Joined: 17-March 11

Re: segmentation fault driving me buggy

Posted 04 February 2012 - 09:22 AM

17	            face = this_card % 13;
18	            suit = this_card / 13;
19	            // stuff these values into the arrays
20	            our_hand_card[this_card]=face;
21	            our_hand_suit[this_card]=suit;



You use this_card as an index to our_hand_card and our_hand_suit which are arrays with a size of 5 while the lines before it seem to imply that this_card can be 13 and larger.

Anyway, learning to use a debugger is a necessary skill to do any serious C/C++ programming, you should familiarize yourself with one.
Was This Post Helpful? 0
  • +
  • -

#6 Bryston  Icon User is offline

  • D.I.C Head

Reputation: 15
  • View blog
  • Posts: 122
  • Joined: 24-January 12

Re: segmentation fault driving me buggy

Posted 04 February 2012 - 09:48 AM

View PostKarel-Lodewijk, on 04 February 2012 - 09:22 AM, said:

17	            face = this_card % 13;
18	            suit = this_card / 13;
19	            // stuff these values into the arrays
20	            our_hand_card[this_card]=face;
21	            our_hand_suit[this_card]=suit;



You use this_card as an index to our_hand_card and our_hand_suit which are arrays with a size of 5 while the lines before it seem to imply that this_card can be 13 and larger.

Anyway, learning to use a debugger is a necessary skill to do any serious C/C++ programming, you should familiarize yourself with one.


this_card is returned from an array of 52 randomly generated numbers ranging from 0 to 51, I have tested this extensively and the value of this_card only ever exceeds this AFTER trying to change the card stored in the players hand array. i'm pretty sure the error is in dereferencing the pointer while writing the new card into the previously dealt hand and is likely because of my shaky understanding of pointers.

i am currently using Dev C++, and i am aware it isnt recommended to use it but its all i have for now, if anyone can recommend a better free compiler i would be all over it.

if i can suck enough bandwidth out of this pipe i will try getting the express version of visual c++.
Was This Post Helpful? 0
  • +
  • -

#7 jimblumberg  Icon User is offline

  • member icon

Reputation: 1892
  • View blog
  • Posts: 5,681
  • Joined: 25-December 09

Re: segmentation fault driving me buggy

Posted 04 February 2012 - 09:52 AM

I would recommend code::blocks instead of Visual C if you are having problems with long download times. Just make sure you download the version with the mingw compiler.

Also without seeing more code the following line looks suspect:
int dealer(void* deal_player_array){


What is the purpose of using a void*? Why are you not passing the correct type of variable into this function?


Jim

This post has been edited by jimblumberg: 04 February 2012 - 09:55 AM

Was This Post Helpful? 0
  • +
  • -

#8 Bryston  Icon User is offline

  • D.I.C Head

Reputation: 15
  • View blog
  • Posts: 122
  • Joined: 24-January 12

Re: segmentation fault driving me buggy

Posted 04 February 2012 - 09:58 AM

View Postjimblumberg, on 04 February 2012 - 09:11 AM, said:

Without a complete program that demonstrates the problem trying to find a segmentation fault is like trying to find a needle in a haystack. One thing I would suggest is you start using std::vector and std::string to eliminate most of the dynamic memory allocations.

What compiler, IDE and operating system are you using? How to use the debugger depends on which compiler, IDE you are using. Without this information I can not point you to documentation on using your debugger.

Do you have your compiler generating warnings as well as errors? Most compilers do not by default generate warnings, you must change settings, or add compile time switches to enable warning generation. Trying to write reliable programs with just errors is very difficult if not impossible.

Jim


I could post the complete code but don't want to make it look like I am trying to get someone to solve my problem for me.

I'm using Dev C++ on windows 7 64 bit.

I am using the arrays (for now) because I want to find out why the problem is happening. I could get the program working easily by creating static arrays, or vectors, or strings, but that would be the easy thing to do ;)

I figure by the time I get it worked out I will not have to be afraid of pointers anymore!!!
Was This Post Helpful? 0
  • +
  • -

#9 Bryston  Icon User is offline

  • D.I.C Head

Reputation: 15
  • View blog
  • Posts: 122
  • Joined: 24-January 12

Re: segmentation fault driving me buggy

Posted 04 February 2012 - 10:06 AM

View Postjimblumberg, on 04 February 2012 - 09:52 AM, said:

I would recommend code::blocks instead of Visual C if you are having problems with long download times. Just make sure you download the version with the mingw compiler.

Also without seeing more code the following line looks suspect:
int dealer(void* deal_player_array){


What is the purpose of using a void*? Why are you not passing the correct type of variable into this function?


Jim


I got that from a tutorial on pointers.

/*************************************************************************/
/*  poker.cpp: -- a simple draw poker simulator for (n) players          */
/*                                                                       */
/*  Author: -- Bryston                                                   */
/*                                                                       */
/*  PURPOSE: -- to get a better grasp on basic concepts                  */
/*                                                                       */
/*  USAGE: -- follow the on screen instructions                          */
/*                                                                       */
/*************************************************************************/

#include<iostream>
#include<ctime>

using namespace std;// so we don't have to use verbose std::cin etc...

// function prototypes
signed int randomizer(signed int n);
int next_available(int n);
int welcome_display();
void shuffle();
int dealer(void* deal_player_array);
int draw(void* draw_player_array);
void display_results(void* player_array);
int get_choice(int card_choice);


// Global Variables
int cards_to_deal(5);
int players(0);
int card_drawn[52];
int cards_remaining = 52;
char *suits[4] = {"Hearts", "Clubs", "Diamonds", "Spades"};
char *faces[13] = {"Two", "Three", "Four", "Five", "Six", "Seven", 
                  "Eight", "Nine", "Ten", "Jack", "Queen", "King", "Ace"};
char *player_names[6] = {"Walter", "Horace", "Jeremiah", "Mabel",
                         "Phineas", "Annette"};                  


/**************************************************************************
******************************** WARNING **********************************
******************* IF YOU STEAL THIS CODE AND SUBMIT IT ******************
***************** AS YOUR HOMEWORK YOU MAY FAIL YOUR COURSE****************
*********** AND END UP FLIPPING BURGERS FOR THE REST OF YOUR LIFE**********
***************************************************************************
**************************************************************************/

int main(){
    // seed the randomizer with system time
    srand(time(NULL));

    while(1){// start while loop so program repeats until user exits

//>>>>>>>>>>>>>>>>>>>> Initial Display Section <<<<<<<<<<<<<<<<<<<<<<<<<<<<
    welcome_display();
     

//>>>>>>>>>>>>>>>>>>>> Get User Input Section <<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    cout << "Enter the # of players (0) to exit :> "; 
    cin >> ws;
    cin >> players;
    if (players == 0)
        break;    

//>>>>>>>>>>>>>>>>>>>>> Process Data Section <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    // create the arrays to hold the players hands
    // first create an array to hold the address to each player
    int** player_array_ptr = new int*[ players ];
    // now create an array for each players hand
    for (int array_player = 0; array_player < players; array_player++){
        player_array_ptr[array_player] = new int[cards_to_deal];
        }
    
    // shuffle the deck
    shuffle();
    // deal the cards
    for (int player = 0; player < players; player++){
        dealer(player_array_ptr[player]);
        }
    for (int player = 0; player < players; player++){
        cout << "_______________________________________________" << endl;
        cout << endl << player_names[player];
        cout << " Was dealt: " << endl << endl;
        display_results(player_array_ptr[player]);
        cout << "________________________________________________" << endl;
        cout << endl;
        }
    // draw new cards    
    for (int player = 0; player < players; player++){
        cout << player_names[player] << " ";
        draw(player_array_ptr[player]);
        }
    for (int player = 0; player < players; player++){
        cout << "_______________________________________________" << endl;
        cout << endl << player_names[player];
        cout << " Was dealt: " << endl << endl;
        display_results(player_array_ptr[player]);
        cout << "________________________________________________" << endl;
        cout << endl;
        }

//>>>>>>>>>>>>>>>>>>>> Display Results Section <<<<<<<<<<<<<<<<<<<<<<<<<<<<


//>>>>>>>>>>>>>>>>>>>>>>>>> Cleanup Section <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
    //delete the dynamic arrays to avoid a memory leak
    for (int delete_player = 0; delete_player < players; delete_player++)
        delete[] player_array_ptr[ delete_player ];
    delete[] player_array_ptr;
}// end while loop
    
    return (0);    
}// end function main


/*************************************************************************/
/*                            FUNCTIONS                                  */
/*************************************************************************/

int welcome_display(){
    system ("cls");
    cout << "                     ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»";
    cout << endl;
    cout << "                     º  A 5 card stud poker simulator.  º";
    cout << endl;
    cout << "                     º      Written by Tim Graham.      º";
    cout << endl;   
    cout << "                     ÈÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍͼ";
    cout << endl << endl;
    cout << "A maximum of 10 players can sit at the table." << endl;
    cout << "Each players will be dealt 5 cards." << endl;
    cout << "Each player will deal in turn." << endl;
    cout << "The deal will pass around the table clockwise." << endl;
    cout << endl;

}// end function welcome_display


void shuffle(){
     cout << endl << "Shuffling ";
     //reset the deck to 52 cards
     cards_remaining = 52;
     //reset to show all cards as available 
     for(int i = 0; i < 52; i++){
        card_drawn[i]=(false); //reset to show all cards as available
        }
     cout << endl << endl; 
}//end shuffle


int dealer(void* deal_player_array){
    // get temporary access to the players hand array
    int* deal_access=(int*)deal_player_array;   
    // declare our variables for this function
    int suit, face, n, this_card, new_card;
    // set up temporary arrays to hold the hands values
    int our_hand_card [5];
    int our_hand_suit [5];
    // loop until the player has 5 cards
     for (int card = 0; card < cards_to_deal; ++card){
         // tell the randomizer to decrement
         n = randomizer(cards_remaining--);
         // get the next available card
         this_card = next_available(n);
         // modulo and divide to get value for face and suit
         face = this_card % 13;
         suit = this_card / 13;
         // stuff these values into the arrays
         our_hand_card[card]=face;
         our_hand_suit[card]=suit;
         // get a unique int representing suit and face
         new_card=((suit*100)+(face));
         // put the cards unique int into the players hand
         deal_access[card]=new_card;
         }
     return(0);
}// end function dealer


int draw(void* draw_player_array){
    // get temporary access to the players hand array
    int* draw_access=(int*)draw_player_array;   
    // declare our variables for this function
    int suit, face, n, this_card, new_card;
    // set up temporary arrays to hold the hands values
    int our_hand_card [5];
    int our_hand_suit [5];
    for (int card = 0; card < 5; card++){
        if (get_choice(card) == 1){ // start if
            // replace a card
            // tell the randomizer to decrement
            n = randomizer(cards_remaining--);
            // get the next available card
            this_card = next_available(n);

            // modulo and divide to get value for face and suit
            face = this_card % 13;
            suit = this_card / 13;
            // stuff these values into the arrays
            our_hand_card[this_card]=face;
            our_hand_suit[this_card]=suit;
            // get a unique int representing suit and face
            new_card=((suit*100)+(face));
            // put the cards unique int into the players hand
            draw_access[card]=new_card;
            }// end if
    }// end for
return(0);
}// end function draw


int get_choice(int card_choice){
    cout << "Do you want to keep card " << card_choice << "? :> ";
    cout << "\ty / n  :> " ;
    char choice;
    cin >> ws;
    cin >> choice;
    switch(choice) {
        case 'y':
            return (0);
        case 'n':
            return (1);
        default:
            cout << "Didn't understand input!";
            cin.ignore(100,'\n');
    }// end switch
}// end function get_choice


void display_results(void* player_array){
     // get temporary access to the players hand array
    int* display_access=(int*)player_array;
     
    // loop through the players one at a time and show their cards
    for (int card = 0; card < cards_to_deal; card++){
        // modulo to extract face value
        cout << faces[display_access[card]%100] << " of ";
        // divide to extract suit value
        cout << suits[display_access[card]/100] << "     ";
        }
    cout << endl;
}// end function display_result

int next_available(int n){
    int i = 0;
    while (card_drawn[i]){
          i++;
          }
    while (n-- > 0){
          i++;
          while (card_drawn[i])
                i++;
          }
          card_drawn[i]=true;
    return i;
}//end next_available

signed int randomizer(signed int n){
    return rand() % n;
}//end function randomizer

                                                                             


Was This Post Helpful? 0
  • +
  • -

#10 jimblumberg  Icon User is offline

  • member icon

Reputation: 1892
  • View blog
  • Posts: 5,681
  • Joined: 25-December 09

Re: segmentation fault driving me buggy

Posted 04 February 2012 - 10:08 AM

Without the source finding a segmentation fault would, in my opinion, just be a guessing game.

Here is a link to basic debugging with DevC++ and a more in depth tutorial.

Jim
Was This Post Helpful? 1
  • +
  • -

#11 Oler1s  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 1282
  • View blog
  • Posts: 3,659
  • Joined: 04-June 09

Re: segmentation fault driving me buggy

Posted 04 February 2012 - 10:29 AM

> I got that from a tutorial on pointers.

Find another tutorial.

int dealer(void* deal_player_array){
	// get temporary access to the players hand array
	int* deal_access=(int*)deal_player_array;



Doesn't something feel wrong in your mind? If you're going to cast immediately, why not just pass in the right datatype, hmmm???
Was This Post Helpful? 1
  • +
  • -

#12 Bryston  Icon User is offline

  • D.I.C Head

Reputation: 15
  • View blog
  • Posts: 122
  • Joined: 24-January 12

Re: segmentation fault driving me buggy

Posted 04 February 2012 - 10:39 AM

View PostOler1s, on 04 February 2012 - 10:29 AM, said:

> I got that from a tutorial on pointers.

Find another tutorial.

int dealer(void* deal_player_array){
	// get temporary access to the players hand array
	int* deal_access=(int*)deal_player_array;



Doesn't something feel wrong in your mind? If you're going to cast immediately, why not just pass in the right datatype, hmmm???


That's my bad. the function was originally a void, while trying to get things working i changed it to an int. I will try passing in as int and see what that does, but if my memory serves I tried that about 2 o'clock this morning with the same results.
Was This Post Helpful? 0
  • +
  • -

#13 jimblumberg  Icon User is offline

  • member icon

Reputation: 1892
  • View blog
  • Posts: 5,681
  • Joined: 25-December 09

Re: segmentation fault driving me buggy

Posted 04 February 2012 - 10:43 AM

One of the big problems debugging this program will be the use of so many global variables.

Quote

I am using the arrays (for now) because I want to find out why the problem is happening. I could get the program working easily by creating static arrays, or vectors, or strings, but that would be the easy thing to do


I would recommend that you get the program working with static arrays, then after you have that working go to the more complicated dynamic memory.

Quote

What is the purpose of using a void*? Why are you not passing the correct type of variable into this function?

Quote

I got that from a tutorial on pointers.


I would say throw away that tutorial. Passing parameters should be done by using the correct pointer type, using void pointers should be avoided in most cases. Here is a better tutorial, along with this.

I would also recommend you read the function tutorials linked below in my signature.

Also Karel-Lodewijk pointed you to one place where your program is definitely accessing an array out of bounds, which is one place where your program is crashing. Re-read post #5 if your this_card variable value is over 4 you will have problems. I ran the program with 2 players and at one point this_card was equal to 10 and the program crashed.

Jim

This post has been edited by jimblumberg: 04 February 2012 - 10:46 AM

Was This Post Helpful? 2
  • +
  • -

#14 Bryston  Icon User is offline

  • D.I.C Head

Reputation: 15
  • View blog
  • Posts: 122
  • Joined: 24-January 12

Re: segmentation fault driving me buggy

Posted 07 February 2012 - 12:53 PM

Thanks for the tips guys, most helpful.
Tried it with static arrays and had the same problem. Found out how to use the debugger a bit and set a few watches and some breakpoints, traced it down and found that my understanding of scopes was a little less than what was required. Got rid of some of the globals, redid some of the logic and renamed some of the variables.
Works like a champ now, just needs a little more optimization, but that can wait as I'm on to the next chapter: It don't mean a thing if it ain't got that string!
After that comes classes so I will revisit the program with an eye towards moving the cards into a class and take the optimization from there.

Really appreciate the help.
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1