C:具有重复指针数组的结构没有指向正确的位置,并且具有垃圾值

qv7cva1a  于 2023-08-03  发布在  其他
关注(0)|答案(1)|浏览(63)

我有一个名为“deck”的结构体,它有一个带结构体的数组。以下是结构体:

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

typedef enum suits {Clubs, Diamonds, Hearts, Spades} suits;
typedef struct card{

    int rank;

    //Suit: Clubs ♣, Diamonds ♦, Hearts ♥, Spades ♠
    suits suit;
}card;

#define SUITAMOUNT 4
#define DECKLENGTH 13
#define CARDSINADECK DECKLENGTH*SUITAMOUNT
typedef struct deck {
    card cards[CARDSINADECK];

} deck;

#define DECKAMOUNT 8
#define CARDSINASHOE DECKAMOUNT*CARDSINADECK
typedef struct shoe {
    uint topOfShoe;

    card * cards[CARDSINASHOE];

} shoe;

字符串
我创建的“甲板”是这样的:

static deck createDeckOfCards()
{
    deck deckOfCards;

    for ( suits suitType = Clubs; suitType <= Spades; suitType++) {

        uint offset = DECKLENGTH * suitType;
        for (int rankNumer = 0; rankNumer < DECKLENGTH ; rankNumer++) {
            uint posInArray = rankNumer + offset;

            /* card *newCard = createCard(rankNumer + 1, suitType); */
            card newCard = { .rank = rankNumer + 1, .suit = suitType };
            deckOfCards.cards[posInArray] = newCard;
        }
    }

    return deckOfCards;
}


这个很好用。所有的牌都正确地存储在deck结构中。然而,当我试图存储指向deck数组的指针时,我得到了垃圾值。我这样存储它们:

static shoe createShoeFromDecks(deck deckOfCards)
{
    shoe shoeOfCards;
    for (int nShoe =0; nShoe < DECKAMOUNT; nShoe++) {

        uint offset = CARDSINADECK * nShoe;
        for (int rankNumer = 0; rankNumer < CARDSINADECK; rankNumer++) {
            uint posInArray = rankNumer + offset;

            card *cardptr = &deckOfCards.cards[rankNumer];
            shoeOfCards.cards[posInArray] = cardptr;
        }
    }

    return shoeOfCards;
}


这将遍历'deck'的卡片数组,并将指向该卡片(card *cardptr = &deckOfCards.cards[rankNumer];)的指针存储在shoe(shoeOfCards.cards[posInArray] = cardptr;)中
最小重现性示例:

void main()
{
    deck deckOfCards;
    deckOfCards = createDeckOfCards();

    shoe shoeOfCards = createShoeFromDecks(deckOfCards);

    for (int i = 0; i < CARDSINASHOE; i++ ) {
        printf("%d %d \n", shoeOfCards.cards[i]->rank,shoeOfCards.cards[i]->suit);
    }


我得到随机垃圾值:
每次运行程序时,其中一些值都会更改。
如何正确存储指针?

pvcm50d1

pvcm50d11#

我认为问题出在你的函数createShoeFromDecks

static shoe createShoeFromDecks(deck deckOfCards)
{
    shoe shoeOfCards;
    for (int nShoe =0; nShoe < DECKAMOUNT; nShoe++) {

        uint offset = CARDSINADECK * nShoe;
        for (int rankNumer = 0; rankNumer < CARDSINADECK; rankNumer++) {
            uint posInArray = rankNumer + offset;

            card *cardptr = &deckOfCards.cards[rankNumer];
            shoeOfCards.cards[posInArray] = cardptr;
        }
    }

    return shoeOfCards;
}

字符串
您将deckOfCards作为值传递,这将导致创建一个本地deckOfCards变量,该变量在退出函数后被销毁(从堆栈中删除)。

card *cardptr = &deckOfCards.cards[rankNumer];


这将返回一个指向局部变量的指针。
要解决这个问题,你可以简单地改变你的函数的原型,通过引用(或指针)传递你的deckofCards对象:

static shoe createShoeFromDecks(deck* deckOfCards)
{
    shoe shoeOfCards;
    for (int nShoe =0; nShoe < DECKAMOUNT; nShoe++) {

        uint offset = CARDSINADECK * nShoe;
        for (int rankNumer = 0; rankNumer < CARDSINADECK; rankNumer++) {
            uint posInArray = rankNumer + offset;
            // Note that -> which means dereferencing a pointer.
            card *cardptr = &(deckOfCards->cards[rankNumer]);
            shoeOfCards.cards[posInArray] = cardptr;
        }
    }

    return shoeOfCards;
}


然后当你调用它时,传递地址而不是变量本身:

shoe shoeOfCards = createShoeFromDecks(&deckOfCards);


我还没有测试过,但我几乎可以肯定你会得到更好的结果。

相关问题