MCkea444
MCkea444

Reputation: 15

segmentation fault when trying to pass two array pointers to a function that swaps them randomly

I am trying to swap two pointers in the same array 52 times using a function within a for-loop. I am getting a segmentation fault and i'm not sure where the issue is.

Here's my code:

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "shuffle.h"

extern void shuffle(int** tempPtr1 , int** tempPtr2);
extern void deal(int numPlayers, int numHands, int** tempPtr2);

int main(void) {
    int numPlayers;
    int numHands;
    int randomNum;

    printf("Enter number of players: ");
    scanf("%d", &numPlayers);

    printf("Enter number of hands per player: ");
    scanf("%d", &numHands);

    int card[52] = {0};
    char faces[] = {'A', '2', '3', '4', '5', '6', '7', '8', '9','X', 'J', 'Q', 'K'};
    char suit[] = {'S', 'D', 'H', 'C'};

    srand((unsigned)time(NULL));

    for(int i = 0; i < 52; i++) {

        card[i] = suit[i/13];
        card[i] = card[i] << CHAR_BIT;
        card[i] = card[i] | faces[i%13];
    }
    int *firstIndxPtr;
    firstIndxPtr = &card[0];
    int *randIndxPtr1;

    for(int i = 0; i<52;i++){
        randomNum = rand() % 52 + 1;
        randIndxPtr1 = &card[randomNum];
        shuffle(&firstIndxPtr, &randIndxPtr1);
    }
    deal(numPlayers, numHands, &firstIndxPtr);
}

and then my function shuffle:

#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void shuffle(int** tempPtr1 , int** tempPtr2);

void shuffle(int** tempPtr1 , int** tempPtr2)
{       
    int* tempPtr = *tempPtr2;
    *tempPtr2 = *tempPtr1;
    *tempPtr1 = tempPtr;
}

the function should swap the pointer address of the 0 index in the card array with the pointer address of a random index in the card array. This would then be done 52 times in the for loop, creating a fully shuffled array. Instead I get a segmentation fault.

Upvotes: 0

Views: 71

Answers (2)

Panos Antoniadis
Panos Antoniadis

Reputation: 108

The problem is:

 randomNum = rand() % 52 + 1;

Because rand()%52 is a number between 0 and 51. So, after adding 1 you have a number between 1 and 52. In case, rand()%52 is 51 randomNum is 52 and here:

randIndxPtr1 = &card[randomNum];

you access index 52 in an array with size 52. So, don't add 1 to randomNum.

Upvotes: 1

manveti
manveti

Reputation: 1711

I spot two overruns in the posted code which could lead to a segfault:

First, rand() % 52 + 1 ranges from 1 to 52, inclusive, which means roughly 2% of the time card[randomNum] will be past the end of card.

Second, shuffle swaps which addresses two pointers point to, not the contents of the memory at those two addresses. So shuffle(&firstIndxPtr, &randIndxPtr1) just changes where in the (unmodified) card array firstIndxPtr and randIndxPtr1 point. Because randIndxPtr1 is always at least the second element of card, firstIndxPtr is guaranteed to be past the start of card at the end of this (as above, it may even end up past the end of card). Presumably deal expects to be able to access 52 elements of card when at most 51 elements (possibly as few as -1) are actually available past firstIndexPtr.

Upvotes: 0

Related Questions