简体   繁体   中英

Assign a Struct Pointer to Double Pointer Struct

The problem: Create a struct with double pointer to be ale to sort the cards without changing the memory location of each card.

The cards are used in other parts of the program.

Diagram:

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

Code:

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;
}

The code is compiling without errors, but the sort changes the memory address of the cards.

The way I am using to link the **cards to the struct card is the correct way of doing this?

To sort the cards I'm using qsort.

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

If your goal is to sort hand2->cards , which is of type card_t ** , then you need to pass sizeof(card_t*) to qsort , and make sure your comparison function accepts card_t ** as inputs.

Ie

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

and

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;
}

(Update)

Perhaps this diagram can clarify what you have allocated, after calling add_card_to three times. You will have deck->cards point to a chunk in memory containing three pointers, and each of the pointers will point to a separately allocated card.

The qsort call is currently reordering the array of pointers, ie swapping the order of pointers inside the array pointed by deck->cards . It also works by accident, because sizeof(card_t) is equal to sizeof(card_t*) on your 64-bit machine.

                 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                   | 
                    +----+---+                   |
                    |    |   |<------------------+
                    +----+---+                   

Your add_card_to function is also copying struct values to the heap-allocated space. This means that the cards added to the deck are not the same cards as in your main program.

If you are also allocating the cards outside this function, then you need to change the function to simply:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM