问题:创建带有双指针的结构以便在不更改每张卡的存储位置的情况下对卡进行排序。
卡在程序的其他部分使用。
图:
*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);
答案 0 :(得分:1)
如果您的目标是对hand2->cards
类型为card_t **
的{{1}}进行排序,则需要将sizeof(card_t*)
传递给qsort
,并确保比较函数接受{ {1}}作为输入。
即
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;
}
3次之后,该图可以澄清您分配的内容。您将add_card_to
指向包含三个指针的内存块,每个指针将指向单独分配的卡。
deck->cards
调用当前正在对指针数组重新排序,即在qsort
指向的数组内交换指针的顺序。由于deck->cards
等于您的64位计算机上的sizeof(card_t)
,因此它也是偶然起作用的。
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