首页 > 解决方案 > 将指针改组到指向结构的指针

问题描述

我的代码中有 2 个结构;card(value, suit)deck(**cards, n),我正在尝试洗牌里面的牌。

shuffle()函数的 for 循环内部。

第一张卡片之后的第 i 张卡片保存在temp_card

随机选择一张卡片并将其分配给第 i 张卡片。

temp_card分配给随机卡。

问题是程序在这一行停止执行可能是由于分段错误。

**(d->cards + i) = **(d->cards + random_number);

我尝试使用 gdb 进行调试,但不是很具体。这是代码。我还添加了一些卡片和卡片组以main()对其进行测试,但我对 C 语言还很陌生,所以我也可能会搞砸这些指针的内存位置。

我的改组方法是否正确,或者我应该改变它,为什么程序停在该行,是因为我提供的指针无效吗?

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

#define VALUE_ACE 14
#define VALUE_KING 13
#define VALUE_QUEEN 12
#define VALUE_JACK 11

typedef enum {
  SPADES,
  HEARTS,
  DIAMONDS,
  CLUBS,
  NUM_SUITS
} suit_t;

struct card_tag {
  unsigned value;
  suit_t suit;
};
typedef struct card_tag card_t;

struct deck_tag {
  card_t ** cards;
  size_t n_cards;
};
typedef struct deck_tag deck_t;

void shuffle(deck_t * d){   

    card_t temp_card;
    int n = d->n_cards;
    int random_number;

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

        temp_card = **(d->cards + i);

        random_number = rand() % n;

        **(d->cards + i) = **(d->cards + random_number);
        **(d->cards + random_number) = temp_card;
    }       
}

int main(){
    deck_t deck;

    card_t card1;
    card1.suit = 1;
    card1.value = 1;
    card_t *c_ptr = &card1;
    card_t **c_pptr = &c_ptr;

    card_t card2;
    card2.suit = 2;
    card2.value = 2;
    card_t *c_ptr2 = &card2;
    card_t **c_pptr2 = &c_ptr2;

    card_t card3;
    card3.suit = 0;
    card3.value = 5;
    card_t *c_ptr3 = &card3;
    card_t **c_pptr3 = &c_ptr3;

    card_t card4;
    card4.suit = 2;
    card4.value = 2;
    card_t *c_ptr4 = &card4;
    card_t **c_pptr4 = &c_ptr4;

    deck.cards = c_pptr;

    deck.n_cards = 4;

    deck_t *d_ptr = &deck;

    shuffle(d_ptr); 
}

标签: cpointersstructsegmentation-faultshuffle

解决方案


正如评论中已经指出的那样(来自 Barmar & Weather Vane),您的代码不会将 4 张牌插入牌组。只插入第一张牌,其余三张牌与牌组无关。

您需要做的是使用动态分配,以便您可以分配一组卡片。数组的大小必须与一副牌的数量相匹配。

但首先……在套牌中使用双指针似乎很奇怪。因此,首先将其更改为“单个”指针 - 例如:

struct deck_tag {
  card_t * cards; // Only one *
  size_t n_cards;
};

然后在main做类似的事情:

int main(){
    deck_t deck;
    deck.n_cards = 4;
    deck.cards = malloc(deck.n_cards * sizeof *deck.cards);
    if (!deck.cards) exit(1);

    // Now you have 4 cards in the deck and you can 
    // insert card values directly into the deck.
    // There is no need for variables like card1, card2, card3 ...
    deck.cards[0].suit = 1;
    deck.cards[0].value = 1;

    deck.cards[1].suit = 2;
    deck.cards[1].value = 2;

    ... and so on (or better... use loops)


    shuffle(d_ptr); 

    free(deck.cards);
    return 0;
}

此外,您还需要更新 shuffle 代码以使用“单个”指针。


推荐阅读