Вхождение в ошибку сегментации при создании массива структуры - PullRequest
0 голосов
/ 19 февраля 2020

По какой-то причине я не могу понять, почему я сталкиваюсь с ошибкой сегментации. Я создал массив типа «Карта», который должен содержать 5 карт. Затем в руку я хочу добавить масть и лицо к каждой карточке в этом массиве.

Я думаю, что проблема либо в типе данных (постоянных или непостоянных ??), когда что-то передает массив и обращается к нему в новой функции ИЛИ с правильным распределением памяти.

Пожалуйста, помогите! Спасибо.

Вот мой код для создания "руки" пользователя. Здесь происходит ошибка сегментации

// Make the user's hand here
void makeHand(const Card * deck, Card * cardArray[5]){
    // loop through Deck
    for (size_t i = 0; i < 5; ++i) {
        printf("%5s of %-8s%s", deck[i].face, deck[i].suit,
               (i + 1) % 4 ? "  " : "\n");

        cardArray[i]->face = malloc(sizeof(char) * 25);
        strcpy(cardArray[i]->face, deck[i].face);

        cardArray[i]->suit = malloc(sizeof(char) * 25);
        strcpy(cardArray[i]->suit, deck[i].suit);
    }
}

Вот моя основная функция:

int main(void){
   Card deck[CARDS]; // define array of Cards

   // initialize array of pointers
   const char *face[] = { "Ace", "Two", "Three", "Four", "Five",
      "Six", "Seven", "Eight", "Nine", "Ten",
      "Jack", "Queen", "King"};

   // initialize array of pointers
   const char *suit[] = { "Hearts", "Diamonds", "Clubs", "Spades"};

   srand(time(NULL)); // randomize

   fillDeck(deck, face, suit); // load the deck with Cards
   shuffle(deck); // put Cards in random order
   deal(deck); // deal all 52 Cards

   // Make an array that holds 5 cards, initialize to 0
   Card cardArray[5];
   makeHand(deck, cardArray);

   //twoPair(cardArray);
} 

Общие определения:

#define CARDS 52
#define FACES 13

// card structure definition                  
struct card {                                 
    const char *face; // define pointer face
    const char *suit; // define pointer suit
}; 

typedef struct card Card; // new type name for struct card   

// prototypes
void fillDeck(Card * wDeck, const char * wFace[],
   const char * wSuit[]);
void shuffle(Card * wDeck);
void deal(const Card * wDeck);

// Make a 5 card hand and return it
// should return an array of 5 cards
void makeHand(const Card * deck, Card * cardArray[5]);

// Definitions to check for each condition
void twoPair(Card *cardArray[5]);

Ответы [ 2 ]

0 голосов
/ 19 февраля 2020

Правильный код:

void makeHand(const Card * deck, Card *cardArray){
    // loop through Deck
    for (size_t i = 0; i < 5; ++i) {
        printf("%5s of %-8s%s", deck[i].face, deck[i].suit,
               (i + 1) % 4 ? "  " : "\n");

        cardArray[i].face = malloc(sizeof(char) * 25);
        strcpy(cardArray[i].face, deck[i].face);

        cardArray[i].suit = malloc(sizeof(char) * 25);
        strcpy(cardArray[i].suit, deck[i].suit);
    }
}

Возможно, вы хотите использовать cardArray[5];, определенный в main? А пока вы берете массив, используете его элементы в качестве указателей (они не указывают нигде на действительные значения) и пытаетесь найти там структуры Card (и записываете в эти несуществующие «лица» и «костюмы».

0 голосов
/ 19 февраля 2020

Я полагаю, что ваша проблема заключается в вашем понимании указателей.

По сути, пометка переменной * и превращение ее в "массив" с [] делают очень похожие вещи. Они ОБА делают указатель, но с помощью оператора [] вы указываете системе длину массива. Переменная содержит адрес памяти точки в памяти, а массив, перед разыменованием, содержит адрес памяти точки в памяти. ваша функция:

void makeHand(const Card * deck, Card * cardArray[5]){
    // loop through Deck
    for (size_t i = 0; i < 5; ++i) {
        printf("%5s of %-8s%s", deck[i].face, deck[i].suit,
               (i + 1) % 4 ? "  " : "\n");

        cardArray[i]->face = malloc(sizeof(char) * 25);
        strcpy(cardArray[i]->face, deck[i].face);

        cardArray[i]->suit = malloc(sizeof(char) * 25);
        strcpy(cardArray[i]->suit, deck[i].suit);
    }
}

Эта функция принимает указатель (массив) типа Card с именем deck и указатель (массив) массива типа Card с именем cardArray. Затем вы вызываете эту функцию следующим образом:

makeHand (deck, cardArray);

колода - это правильный тип, это указатель типа Card. Однако cardArray - это только массив, а не указатель на массив. Я не уверен, какую именно функциональность вы пытаетесь достичь, но изменение makeHand, чтобы оно выглядело так:

void makeHand(Card* deck, Card* cardArray) {}

должно соответствовать вашим потребностям.

УТОЧНЕНИЕ: указатель не точно такой же вещь как массив, я просто думаю, что это полезное сравнение для понимания разницы между ними.

Card* deck;

и

Card deck[];

будут делать то же самое в памяти

...