Thread: segmentation fault on the last printf

  1. #1
    Registered User
    Join Date
    Apr 2019
    Posts
    808

    segmentation fault on the last printf

    i have the following printf statement in side a double for loop
    Code:
    printf("%s ", player[i].hand[j].card_code);
    On the last iteration of the i for loop ie when i is 1 less than the number of players entered it throws a segmentation fault but is fine before that
    coop

  2. #2
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Maybe card_code isn't initialized properly for that particular player. Are you sure that you don't count past the array's real size?
    Devoted my life to programming...

  3. #3
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    just put more than 2 players in and its always the second iteration of the printf statement. on using the debugger the call to the function deal cards is changing the number of cards dealt to a big negative number
    Code:
    //the for loops
    for (j = 0; j < 5; j++)
        {
            for (i = 0; i < num_of_players; i++)
            {
                deal_cards(num_of_players, 1, j, num_cards_delt, p_deck, player);
                printf("%s ", player[i].hand[j].card_code);
                num_cards_delt++;
            }
        }
    //the function
    void deal_cards(int player_num, int num_of_cards, int num_of_cards_in_hand, int num_cards_delt, Card *p_deck_index, Hand player[])
    {
        int i;
    
        for (i = 0 + num_of_cards_in_hand; i < num_of_cards + num_of_cards_in_hand; i++)
        {
            strcpy(player[player_num].hand[i].card_code, p_deck_index[num_cards_delt].card_code);
        }
    }
    how is it doing that
    coop

  4. #4
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    and why does it throw it when i try to step passed the printf statement

  5. #5
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    Quote Originally Posted by cooper1200 View Post
    and why does it throw it when i try to step passed the printf statement
    Probably because the segfault happens on that line, a buffer overflow is the most likely cause.
    Devoted my life to programming...

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    Where's the rest of the code?
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    sorry here is the whole thing
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <string.h>
    
    enum Suit { SPADES = 0, HEARTS = 1, CLUBS = 2, DIAMONDS = 3};
    enum Card_Value {TWO =2, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE};
    typedef struct
    {
        enum Suit suit;
        enum Card_Value card;
        char card_code[52];
    } Card;
    typedef struct
    {
        char player_name[10];
        Card hand[5];
    }Hand;
    
    void initalize_random_generator(void);
    void shuffle_deck(Card *p_deck_index);
    Card * deck(void);
    char * get_card_code(int suit, int face_value);
    void deal_cards(int player_num, int num_of_cards, int num_of_cards_in_hand, int num_cards_delt, Card *p_deck_index, Hand player[]);
    
    int main()
    {
        int num_of_players;
        int i, j, num_cards_delt = 0;
        Card *p_deck;
    
        initalize_random_generator();
        p_deck = deck();
        for (j = 0; j < 52; j++)
        {
            printf("%s ", p_deck[j].card_code);
        }
        printf("Enter the number of players: ");
        scanf(" %d", &num_of_players);
        // declare variable player array
        Hand player[num_of_players];
    
        for (i = 0; i < num_of_players; i++)
        {
            printf("Please enter player %d's name: ", i + 1);
            scanf(" %s", player[i].player_name);
        }
        for (j = 0; j < 5; j++)
        {
            for (i = 0; i < num_of_players; i++)
            {//      <----- according to the debugger num_cards_delt is still 0 as set in the decleration
                deal_cards(num_of_players, 1, j, num_cards_delt, p_deck, player);
                printf("%s ", player[i].hand[j].card_code);  //<------- when debugger is pointing here ie hasnt done the printf yet num_cards_dealt is -274638395743 or what ever
                num_cards_delt++;
            }
        }
    }
    
    void initalize_random_generator(void)
    {
        srand((unsigned) time(NULL));
    }
    
    Card * deck(void)
    {
        static Card deck[52];
    
        shuffle_deck(deck);
        return deck;
    }
    
    void shuffle_deck(Card *p_deck_index)
    {
        int count_cards = 0, card_found = 0;
        int i;
        int suit_value, face_value;
        char *temp_string;
    
        while (count_cards < 52)
        {
            suit_value = rand() % 4;
            face_value = rand() % 13 + 2;
            for (i = 0; i < count_cards + 1; i++)
            {
                if (p_deck_index[i].suit == suit_value && p_deck_index[i].card == face_value)
                {
                    card_found = 1;
                    break;
                }
            }
            if (!card_found) //card_found is 0
            {
    /*
                p_deck_index[count_cards].suit = suit_value;
                p_deck_index[count_cards].card = face_value;
                temp_string = get_card_code(suit_value, face_value);
                strcpy(p_deck_index[count_cards].card_code, temp_string));
                count_cards ++;
    //*/
                temp_string = get_card_code(suit_value, face_value);
                p_deck_index[count_cards] = (Card) {suit_value, face_value};
                strcpy(p_deck_index[count_cards++].card_code, temp_string);
            }
            card_found = 0;
        }
        for (i = 0; i < 52; i++)
        {
            printf("%s ", p_deck_index[i].card_code);
        }
    }
    
    char * get_card_code(int suit, int face_value)
    {
    /*******************************************
     * Thanks to flp1969 for this code. Suit:  *
     * goes from  0 spades, 1 hearts ,2 clubs, *
     * and 3 is diamonds. Card: ace = 0, 2 = 1,*
     * 3 = 2 ... 10 = 9, J = 10, Q = 11, K = 12*
     *******************************************/
    
        static char s[5] = { 0 };
    
        int c = 0x1f0a1;
    
        if (face_value == ACE)
        {
            face_value -= 14;
        }
        else
        {
            face_value -= 1;
        }
    
        switch ( suit )
        {   //deliberate fall through
            case 2: // clubs
                c += 0x10;
            case 3: // diamonds
                c += 0x10;
            case 1: // hearts
                c += 0x10;
        }
    
        switch ( face_value )
        {
            case 0 ... 10:
                c += face_value;
                break;
            default:
                c += face_value + 1;
        }
    
        s[0] = 0xf0 | ((c >> 18) & 7);
        s[1] = 0x80 | ((c >> 12) & 0x3f);
        s[2] = 0x80 | ((c >> 6) & 0x3f);
        s[3] = 0x80 | (c & 0x3f);
    
        return s;
    }
    
    void deal_cards(int player_num, int num_of_cards, int num_of_cards_in_hand, int num_cards_delt, Card *p_deck_index, Hand player[])
    {
        int i;
    
        for (i = 0 + num_of_cards_in_hand; i < num_of_cards + num_of_cards_in_hand; i++)
        {
            strcpy(player[player_num].hand[i].card_code, p_deck_index[num_cards_delt].card_code);
        }
    }
    Last edited by cooper1200; 05-11-2019 at 10:22 AM.

  8. #8
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Learn how to use a debuger...

  9. #9
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > char card_code[52];
    What's the significance of this?
    Why are there 52 somethings in each card?

    A card has only two parameters, suit and rank.

    It's the deck which has 52 entries in it.

    Oh, and all those pointers to statics are ugly.
    What happens when you have a game involving two decks of cards? You're up the creek without a paddle.

    Your main.
    Code:
    int main ( ) {
        Card deck[52];
        Hand players[2];
        shuffle(deck,52);
        int numDealtCards = 0;
        deal(deck,&numDealtCards,&players[0]);
        deal(deck,&numDealtCards,&players[1]);
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  10. #10
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    the 52 is for the utf8 code. i had an issue earlier assigning the utf8 code and forgot to change it back to 10
    if i wanted to have 2 decks i guess i would change the number to 104 instead of 52 and copy the deck across same as if i wanted 3 or 4 or 5 or 6

  11. #11
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    as to why a function is changing the value of a number it is passed with out a pointer any ideas???

  12. #12
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    changed code
    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <time.h>
    #include <string.h>
    
    enum Suit { SPADES = 0, HEARTS = 1, CLUBS = 2, DIAMONDS = 3};
    enum Card_Value {TWO =2, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE};
    typedef struct
    {
        enum Suit suit;
        enum Card_Value card;
        char card_code[10];
    } Card;
    typedef struct
    {
        char player_name[10];
        Card hand[5];
    }Hand;
    
    void initalize_random_generator(void);
    void shuffle_deck(Card *p_deck_index);
    char * get_card_code(int suit, int face_value);
    void deal_cards(int player_num, int num_of_cards, int num_of_cards_in_hand, unsigned int num_cards_delt, Card *p_deck_index, Hand player[]);
    
    int main()
    {
        int num_of_players;
        int i, j;
        unsigned int num_cards_delt = 0;
        Card deck[52];
    
        initalize_random_generator();
        shuffle_deck(deck);
    
        printf("Enter the number of players: ");
        scanf(" %d", &num_of_players);
        // declare variable player array
        Hand player[num_of_players];
    
        for (i = 0; i < num_of_players; i++)
        {
            printf("Please enter player %d's name: ", i + 1);
            scanf(" %s", player[i].player_name);
        }
        for (j = 0; j < 5; j++)
        {
            for (i = 0; i < num_of_players; i++)
            {
                deal_cards(num_of_players, 1, j, num_cards_delt, deck, player);
                printf("%s ", player[i].hand[j].card_code);
                num_cards_delt++;
            }
        }
    }
    
    void initalize_random_generator(void)
    {
        srand((unsigned) time(NULL));
    }
    
    void shuffle_deck(Card *p_deck_index)
    {
        int count_cards = 0, card_found = 0;
        int i;
        int suit_value, face_value;
        char *temp_string;
    
        while (count_cards < 52)
        {
            suit_value = rand() % 4;
            face_value = rand() % 13 + 2;
            for (i = 0; i < count_cards + 1; i++)
            {
                if (p_deck_index[i].suit == suit_value && p_deck_index[i].card == face_value)
                {
                    card_found = 1;
                    break;
                }
            }
            if (!card_found) //card_found is 0
            {
    /*
                p_deck_index[count_cards].suit = suit_value;
                p_deck_index[count_cards].card = face_value;
                temp_string = get_card_code(suit_value, face_value);
                strcpy(p_deck_index[count_cards].card_code, temp_string));
                count_cards ++;
    //*/
                temp_string = get_card_code(suit_value, face_value);
                p_deck_index[count_cards] = (Card) {suit_value, face_value};
                strcpy(p_deck_index[count_cards++].card_code, temp_string);
            }
            card_found = 0;
        }
        for (i = 0; i < 52; i++)
        {
            printf("%s ", p_deck_index[i].card_code);
        }
    }
    
    char * get_card_code(int suit, int face_value)
    {
    /*******************************************
     * Thanks to flp1969 for this code. Suit:  *
     * goes from  0 spades, 1 hearts ,2 clubs, *
     * and 3 is diamonds. Card: ace = 0, 2 = 1,*
     * 3 = 2 ... 10 = 9, J = 10, Q = 11, K = 12*
     *******************************************/
    
        static char s[5] = { 0 };
    
        int c = 0x1f0a1;
    
        if (face_value == ACE)
        {
            face_value -= 14;
        }
        else
        {
            face_value -= 1;
        }
    
        switch ( suit )
        {   //deliberate fall through
            case 2: // clubs
                c += 0x10;
            case 3: // diamonds
                c += 0x10;
            case 1: // hearts
                c += 0x10;
        }
    
        switch ( face_value )
        {
            case 0 ... 10:
                c += face_value;
                break;
            default:
                c += face_value + 1;
        }
    
        s[0] = 0xf0 | ((c >> 18) & 7);
        s[1] = 0x80 | ((c >> 12) & 0x3f);
        s[2] = 0x80 | ((c >> 6) & 0x3f);
        s[3] = 0x80 | (c & 0x3f);
    
        return s;
    }
    
    void deal_cards(int player_num, int num_of_cards, int num_of_cards_in_hand, unsigned int num_cards_delt, Card *p_deck_index, Hand player[])
    {
        int i;
    
        for (i = 0 + num_of_cards_in_hand; i < num_of_cards + num_of_cards_in_hand; i++)
        {
            strcpy(player[player_num].hand[i].card_code, p_deck_index[num_cards_delt].card_code);
        }
    }

  13. #13
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    now after changing p_deck_index its changing the value of i to some huge negative number

  14. #14
    Registered User
    Join Date
    Apr 2019
    Posts
    808
    changed it so the bloody function doesn't even know about number_of_cards_dealt in fact calculate the number of cards dealt outside of the for loop and it still changes it!!!!!

  15. #15
    TEIAM - problem solved
    Join Date
    Apr 2012
    Location
    Melbourne Australia
    Posts
    1,907
    Deck should be another structure with a member called NumberOfCards.

    You could then dynamically allocate the array, or use a linked list for the cards.

    I personally prefer to use linked list, because you can "remove" the card from the deck, and then "add" it to a hand. In fact, isn't the deck just another hand that belongs to the dealer?...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. In GDB no segmentation fault but while running segmentation fault
    By Tamim Ad Dari in forum C++ Programming
    Replies: 2
    Last Post: 12-10-2013, 11:16 AM
  2. commenting out printf causes segmentation fault
    By zahid990170 in forum C Programming
    Replies: 7
    Last Post: 10-04-2011, 08:38 AM
  3. Segmentation fault on printf() [NOOB ALERT]
    By Richardcavell in forum C Programming
    Replies: 2
    Last Post: 02-26-2011, 06:44 PM
  4. segmentation fault due to "printf" ?
    By MarkZWEERS in forum C++ Programming
    Replies: 4
    Last Post: 09-30-2009, 12:12 PM
  5. segmentation fault and memory fault
    By Unregistered in forum C Programming
    Replies: 12
    Last Post: 04-02-2002, 11:09 PM

Tags for this Thread