将结构指针指定给双指针结构

问题:创建一个带有双指针的结构,以便在不改变每张卡的内存位置的情况下对卡进行排序.

这些卡用于程序的其他部分.

图:

 *deck           .**card    .n_cards 
 +------+       +--------+----+
 |  x---|------>|  x     | 3  |
 +------+       +--------+----+
                   |              +-----+
                   +------------->|  x  |
                                  +-----+
                  .value .suit       |
                    +----+---+       |
                    |    |   |<------+
                    +----+---+
                    |    |   |
                    +----+---+
                    |    |   |
                    +----+---+

码:

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 add_card_to(deck_t * deck, card_t c){
  deck->n_cards++;
  deck->cards = realloc(deck->cards, (deck->n_cards)*sizeof(*deck->cards));
  card_t * new_c = malloc(sizeof(*new_c));
  *new_c = c;
  deck->cards[deck->n_cards-1] = new_c;
  return;
}

代码编译时没有错误,但排序会更改卡的内存地址.

我使用的方式将**卡链接到结构卡是正确的方法吗?

要对卡片进行排序我正在使用qsort.

qsort(hand2->cards, hand2->n_cards, sizeof(card_t), card_ptr_comp);

最佳答案 如果您的目标是对card2-gt;类型的card_t **进行排序,那么您需要将sizeof(card_t *)传递给qsort,并确保您的比较函数接受card_t **作为输入.

qsort(hand2->cards, hand2->n_cards, sizeof *hand2->cards, card_ptr_comp);

int card_ptr_comp(const void * a, const  void * b)
{
    const card_t* card_a = *(const card_t**)a;
    const card_t* card_b = *(const card_t**)b;

    return card_a->suit - card_b->suit;
}

(更新)

也许这个图可以在调用add_card_to三次之后澄清你已分配的内容.你将有deck->卡指向包含三个指针的内存中的一个块,每个指针将指向一个单独分配的卡.

qsort调用当前正在重新排序指针数组,即交换由deck->卡指向的数组内的指针顺序.它也是偶然的,因为sizeof(card_t)等于64位机器上的sizeof(card_t *).

                 card_t**
 *deck           .cards  .n_cards 
 +------+       +--------+----+
 |  x---|------>|  x     | 3  |
 +------+       +--------+----+   YOU ARE REORDERING THIS:
                   |              card_t* card_t* card_t*
                   |              +-----+-----+-----+
                   +------------->|  x  |  y  |  z  |
                                  +-----+-----+-----+
                  .value .suit       |     |     |
                    +----+---+       |     |     |
                    |    |   |<------+     |     |
                    +----+---+             |     |
                                           |     |
                  .value .suit             |     | 
                    +----+---+             |     |
                    |    |   |<------------+     |
                    +----+---+                   |
                                                 |
                  .value .suit                   | 
                    +----+---+                   |
                    |    |   |<------------------+
                    +----+---+                   

您的add_card_to函数还将struct值复制到堆分配的空间.这意味着添加到卡座的卡与主程序中的卡不同.

如果您还要在此功能之外分配卡,则需要将功能更改为:

void add_card_to(deck_t * deck, card_t * c)
{
    deck->n_cards++;
    deck->cards = realloc(...);
    deck->cards[deck->n_cards - 1] = c;
}
点赞