问题:创建一个带有双指针的结构,以便在不改变每张卡的内存位置的情况下对卡进行排序.
这些卡用于程序的其他部分.
图:
*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;
}