【问题标题】:How do I access the members of a pointer to pointer to struct? [duplicate]如何访问指向结构的指针的成员? [复制]
【发布时间】:2019-08-30 06:54:26
【问题描述】:

我正在努力让指针和 C 更自如,所以我一直在做练习题。我有一个结构:

typedef struct Card
{
    enum { hearts, spades, clubs, diamonds } suit;
    int value;
} Card;

还有一个用于为卡组分配内存的函数:

void createDeck(Card ** deck)
{
    deck = malloc(52 * sizeof(Card *)); //allocate space for deck
    if (deck == NULL)
    {
        fprintf(stderr, "malloc failed\n");
        return;
    }

        //allocate memory for each card in deck
    for (size_t i = 0; i < 52; i++)
    {
        *(deck + i) = malloc(sizeof(Card));
    }
}

我正在尝试使用这样的代码:

int main()
{
    Card *deck = NULL;

    createDeck(&deck);

    printf("%d", deck[0].suit)
}

这给出了一个 nullptr 错误,这让我认为我没有正确分配内存。我改变了不同的东西,但无论如何我都无法让它工作。使用createDeck 完成工作后,如何访问deck 的成员?

【问题讨论】:

  • C 中的所有内容都是按值传递的。当您调用createDeck 时会生成deck 的副本,因此对deck 所做的任何修改仅在该副本的函数内是持久的。为了在函数外部查看对deck 的修改,您必须返回它或者(在本例中,因为您已经传递了一个指针),取消引用指针并修改它指向的对象(其范围超出函数)。

标签: c arrays memory-management struct


【解决方案1】:

让我分解你的问题。

main() 中,Card *deck = NULL; 将分配一个指向Card 的指针,并且该指针指向 NULL。

然后你调用createDeck(&amp;deck); 在这里你将指针的地址传递给类型Card。所以,这个地址不是 NULL,因为它指向的是分配在 Card* 类型堆栈上的指针变量。

这意味着在createDeck() 中,变量deck 不会为NULL,它的地址是有效的。但是将指向Card* 类型指针的*deck 将为NULL。你应该只为*deck分配内存。

void createDeck(Card ** deck)
{
    //deck = malloc(52 * sizeof(Card *)); //deck is a double pointer pointing to memory of type Card* allocated on stack in calling function main().
    if (deck == NULL)
    {
        fprintf(stderr, "Null pointer error\n"); //If calling function passes NULL, it means there is some issue.
        return;
    }
    *deck = NULL; //In more complex functions, if there are other logic before doing malloc(), it it better to reset the variables with default values.

        //allocate memory for each card in deck
    //for (size_t i = 0; i < 52; i++)
    //{
    //    *(deck + i) = malloc(sizeof(Card));
    //}

    *deck = malloc(sizeof(Card)*52); //Allocate for all 52 Cards together
    if(NULL == *deck)
    {
        fprintf(stderr, "malloc failed\n");
        return;
    }

    //In case you want to access a card using deck variable.
    (*deck)[2].suit = hearts;
}

【讨论】:

  • 如果我想分配一副52张牌,我只需要使用一个malloc()?
  • @Dumbassahedratron:是的,这在概念上相当于Card[52]缓冲区,但分配在堆上。
  • 是的!您正在为 52 个结构分配空间。如果该类比有帮助,则逻辑与为整数数组分配 10 个元素 (int *arr = malloc(sizeof(int) * 10)) 的逻辑相同。
  • if(NULL != *deck) 正确吗?如果我理解正确,我们正在做一个malloc(),它将为我们分配一个内存块,这意味着它不会是符合条件的NULL,并且总是会触发fprintfreturn?
  • @Dumbassahedratron 我的错。我纠正了它。 :)
【解决方案2】:

没有double pointers,生活总是会更简单,据我所知,您需要一张arry 的卡片(52 张)??

为什么不这样?

Card* createDeck( )
{
    Card *deck = malloc( 52 * sizeof(Card) );
    {
         printf("OOPS");
    }

    return deck;
}

和调用者

Card *deck = createDeck();
if( !deck )
{
   printf("Alloc Failure");
   exit(0);
}

或者最好去掉createDeck,直接调用malloc

Card *deck = malloc( 52 *  sizeof(Card));

如果您想以不同的方式沸腾,这是一个完全不同的主张 例如,一副牌是一组卡片

/* That's how a card looks like */
struct Card{
    int value;
    /* waharever else */
};

/* That's a deck */
struct deck {
   struct Card *cards;
};

现在初始化一个甲板

struct deck *createDeck( )
{
     struct deck *deck = malloc( struct deck );
     if( deck )
     {
         deck->cards = malloc( 52 * sizeof(card));
         if(deck->cards)
         {
            /* Do some thing or leavel it as is */
         }
     }

     return deck;
}

和调用者..

struct *deck = createDeck();
if( !deck )
{
    printf("OOps memory");
    exit(0);
}

【讨论】:

  • 或者干脆 struct deck { struct Card cards[52]; };?
猜你喜欢
  • 2021-12-24
  • 1970-01-01
  • 2022-11-01
  • 1970-01-01
  • 2023-03-12
  • 1970-01-01
  • 2021-12-17
  • 2014-06-09
  • 1970-01-01
相关资源
最近更新 更多