ошибка сегментации при попытке передать два указателя массива в функцию, которая меняет их случайным образом - PullRequest
0 голосов
/ 01 февраля 2019

Я пытаюсь поменять два указателя в одном и том же массиве 52 раза, используя функцию внутри цикла for.Я получаю ошибку сегментации, и я не уверен, где проблема.

Вот мой код:

#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);
}

, а затем моя функция перестановки:

#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;
}

функция должна поменять адрес указателя индекса 0 в массиве карт на адрес указателя случайного индекса в массиве карт.Затем это будет выполнено 52 раза в цикле for, создавая полностью перемешанный массив.Вместо этого я получаю ошибку сегментации.

Ответы [ 2 ]

0 голосов
/ 01 февраля 2019

Проблема в следующем:

 randomNum = rand() % 52 + 1;

Поскольку rand ()% 52 - это число от 0 до 51. Таким образом, после добавления 1 у вас есть число от 1 до 52. В случае, rand ()% 52 - 51 randomNum - это 52, а здесь:

randIndxPtr1 = &card[randomNum];

вы получаете доступ к индексу 52 в массиве с размером 52. Поэтому не добавляйте 1 к randomNum.

0 голосов
/ 01 февраля 2019

Я обнаружил два превышения в опубликованном коде, которые могут привести к segfault:

Во-первых, rand() % 52 + 1 колеблется от 1 до 52 включительно, что означает, что примерно 2% времени card[randomNum] будетпосле конца card.

Во-вторых, shuffle перестановки, на которые указывают два указателя, а не содержимое памяти по этим двум адресам.Таким образом, shuffle(&firstIndxPtr, &randIndxPtr1) просто изменяется где (в неизмененном виде) card массив firstIndxPtr и randIndxPtr1 точка.Поскольку randIndxPtr1 всегда является, по крайней мере, вторым элементом card, firstIndxPtr гарантированно будет проходить после начала card в конце этого (как указано выше, он может даже заканчиваться после конца card).Предположительно deal ожидает, что сможет получить доступ к 52 элементам card, когда максимум 51 элемент (возможно, всего -1) фактически доступен после firstIndexPtr.

...