繁体   English   中英

引用指向结构的指针,该指针包含指向结构的指针

[英]Referencing a pointer to a struct that contains a pointer to a pointer to a struct

我很难引用该结构内部的内存,我不确定我的语法是否正确(尽管考虑到其他帖子,我认为我很好)。 代码在运行时崩溃。 据我所知,我已经分配了所需的内存(52张卡-66行),但是我不确定要应用哪种转换。 我只需要一点点推动和指导,非常感谢!

#include <stdio.h>

#define DECK_SIZE (52)

/* the enum suite definition */
enum suite {
    diamond = 1,
    club,
    heart,
    spade
};

/* the card definition */
struct card {
    int number;
    enum suite type;
};

/* the deck definition */
struct deck {
    struct card ** cards;
    int numCards;
};

/* **
 * Name: addCard(deck *myDeck);
 * Purpose: Add a card to the deck
 ** */
void addCard(struct deck * myDeck)
{
    int number,suiteType;
    printf("Please enter card number: \n");
    scanf("%d",&number);
    printf("Please enter suite type: \n");
    scanf("%d",&suiteType);
    /* increase myDeck->numCards by one */
    myDeck->numCards += 1;
    /* reallocate the block and increase the size by one */
    *(myDeck->cards) = (struct card*) realloc ( *(myDeck->cards), sizeof(struct card) * myDeck->numCards);
    if ( NULL == *(myDeck->cards) ) {
        printf("realloc failed - exiting..\n");
        free( *(myDeck->cards));        
        return;
    }
    /* put the data */
    myDeck->cards[myDeck->numCards-1]->number = number;
    myDeck->cards[myDeck->numCards-1]->type = suiteType;
}

/***
 * Name: initializeDeck();
 * Puspose: create a deck memory block and fill it
 ***/
struct deck * initializeDeck()
 {
    struct deck * myDeck;
    int num,suite,i;
    /* allocate memory for a deck */
    myDeck = (struct deck*) malloc ( sizeof(struct deck) );
    if (NULL == myDeck) {
        printf("Failed to allocate a deck, exiting..\n");
        return 0;
    }
    /* allocte 52 cards */
    myDeck->numCards = DECK_SIZE;
    myDeck->cards = (struct card**) malloc ( sizeof(struct card) * myDeck->numCards );
    if (NULL == *(myDeck->cards)) {
        printf("Failed to allocate 52 cards, exiting..\n");
        free(myDeck);
        return 0;
    }
    /* fill the deck */
    num = 1;
    suite=1;
    for (i = 0; i<DECK_SIZE; i++) {
        myDeck->cards[i]->number = num;
        myDeck->cards[i]->type = suite;
        num++;
        if (num > 13) {
            num = 1;
            suite++;
        }
    }
    return myDeck;
 }

int main()
{
    struct deck * myDeck;
    myDeck = initializeDeck();
    addCard(myDeck);
    return 0;
}

乍一看,我看到两件事(这可能无法解决根本原因,但实际上可以帮助编写更多保存的代码;-)

1.1如果初始化失败,您将返回NULL,但是您不会测试initializeDeck()的结果,而是即使myDeck为NULL也会调用addCard 因此,在初始化期间发生错误的情况下, addCard取消引用myDeck时会导致崩溃。

main()执行以下操作:

[...]
if (myDeck)
  addCard(myDeck);
[...]

甚至更好,在addCard执行以下addCard

void addCard(struct deck * myDeck)
{
  if (!myDeck) {
    printf("invalid input\n");
    return;
  }
  [...]

1.2 malloc()在失败时返回NULL,因此请测试结果并且不要取消引用它:

[...]
myDeck->cards = (struct card**) malloc ( sizeof(struct card) * myDeck->numCards );
if (NULL == myDeck->cards) {
    printf("Failed to allocate 52 cards, exiting..\n");
[...]

仔细观察会发现您显然不确定如何安排数据... ;-)

这条线

myDeck->cards = (struct card**) malloc ( sizeof(struct card) * myDeck->numCards );

应该分配一个指针数组,这些指针的条目然后依次为每张卡分配内存。

所以有两个错误:

2.1您为指向卡指针数组的指针分配了很多内存。

2.2您缺少为卡本身分配内存的信息。

要修复2.1,请将上面的行更改为:

 myDeck->cards = (struct card**) malloc ( sizeof(struct card *) * myDeck->numCards );

要修复2.2,请在分配卡值的循环中添加以下内容。

  [...]
  for (i = 0; i<DECK_SIZE; i++) {
    myDeck->cards[i] = malloc(sizeof(struct card));
    /* adding error checking here is left as an exercise ... */
    myDeck->cards[i]->number = num;
    [...]

添加这两个修复程序可以使您更进一步... ;-)

提示:您在分配卡片组( addCard() )的代码中分配卡组(2.1和2.2)时犯了同样的两个错误。

顺便说一句:对我来说,强制转换malloc()的结果似乎是不必要的,因为malloc()返回的void *与任何指针都兼容。

总而言之,类型转换不是一个好主意,因为它使编译器无法将您指向可能不是应有的方式。

您分配一个数组,其中包含指向卡的指针,但不包含卡本身。

该调用分配了一块myDeck->numCards卡:

malloc ( sizeof(struct card) * myDeck->numCards );

...但是struct card **不是用于保存指向此类块的指针的适当变量。 您应该仅为此成员使用struct card * ,然后使用. 而不是->访问此数组的每个成员:

myDeck->cards[i].number = num;
myDeck->cards[i].type = suite;

使用的规则是type *指向type s(的一个块)。 因此, struct card *用于指向struct card s(的一个块), struct card **指向struct card * s(的一个块)。

如果要在struct card **使用struct card **成员,则需要首先分配一个struct card * s块,以使其指向:

myDeck->cards = malloc (sizeof(struct card *) * myDeck->numCards);
if (NULL == myDeck->cards) {
    fprintf(stderr, "Failed to allocate %d card pointers, exiting..\n", myDeck->numCards);

现在,您可以自己分配卡,将指向卡的指针放在之前分配的指针数组中。 最简单的方法是每张卡分配一个:

for (i = 0; i < myDeck->numCards; i++)
    myDeck->cards[i] = malloc(sizeof(struct card));

您的重新分配应如下所示:

struct card **new_block;

myDeck->numCards += 1;
/* reallocate the block of pointers and increase the size by one */
new_block = realloc (myDeck->cards, sizeof(struct card *) * myDeck->numCards);
if (NULL == new_block) {
    fprintf(stderr, "realloc failed - exiting..\n");
    return;
}
myDeck->cards = new_block;
/* Allocate the new card */
myDeck->cards[myDeck->numCards - 1] = malloc(sizeof(struct card));
if (myDeck->cards[myDeck->numCards - 1] == NULL) {
    fprintf(stderr, "failed to allocate card\n");
    myDeck->numCards--;
    return;
}
/* put the data */
myDeck->cards[myDeck->numCards - 1]->number = number;
myDeck->cards[myDeck->numCards - 1]->type = suiteType;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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