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

发布于 2024-12-10 07:08:31 字数 2410 浏览 1 评论 0原文

我很难引用结构内的内存,我不确定我的语法是否正确(尽管考虑到其他帖子,我认为我很好)。 代码在运行时崩溃。 据我所知,我已经分配了所需的内存(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;
}

I'm having a hard time referencing the memory inside the struct, I'm not sure that my syntax is correct (although considering other posts I think I'm fine).
The code crashes in Run-time.
As far as I'm aware I've allocated the momory needed (52 cards - line 66) but I'm not sure what casting to apply.
I just need that little push and guidance, thanks alot !

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

‘画卷フ 2024-12-17 07:08:31

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

1.1 如果初始化失败,则返回 NULL,但不测试 initializeDeck 的结果() 但即使 myDeck 为 NULL 也调用 addCard。因此,如果初始化期间出现错误,addCard 会在取消引用 myDeck 时导致崩溃。

要么像 main() 中那样执行:

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

或者甚至更好,像 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;
    [...]

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

提示:您在分配牌组(2.1 和 2.2)时犯的两个错误与您在添加卡片的代码中所做的相同(addCard()) 。

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

无论如何,类型转换通常不是一个好主意,因为它使编译器无法将您指向可能不应该的方式。

On the first glance I see two things (which might not solve the root cause, but actually could help in writing more save code ;-))

1.1 If initialising fails you return NULL, but you do not test the result of initializeDeck() but call addCard even if myDeck is NULL. So in case of an error during initialisation addCard causes a crash when dereferencing myDeck.

Either do like follows in main():

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

or and even better and do like follows in addCard:

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

1.2 malloc() returns NULL on failure, so test the result and do not dereference it:

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

Looking closer one realises you are obviously not sure how to arrange your data... ;-)

This line

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

should allocate an array of pointers which's entries then in turn for each card should get memory assigend.

So there are two mistakes:

2.1 You assign to much memory to the pointer referencing the array of pointers to cards.

2.2 You are missing to assign the memory for the cards themselfs.

To fix 2.1 do change the line above into:

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

To fix 2.2 do add the following to the loop assigning the cards' values.

  [...]
  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;
    [...]

Adding those two fixes gets you further ... ;-)

Hint: The same two mistakes you did when allocating the deck (2.1 and 2.2) you do in the code adding a card (addCard()).

Btw: Casting the result of malloc() seems unnecessary to me, as malloc() return void * which is compatible to any pointer.

Anyhow type casting in general is not good idea as it keeps the compiler from pointing you to something which might be not the way it should be.

淡水深流 2024-12-17 07:08:31

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

You allocate an array containing pointers to cards, but not the cards themselves.

吖咩 2024-12-17 07:08:31

此调用分配单个 myDeck->numCards 卡块:

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

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

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

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

如果你想在你的结构体中使用struct card **成员,你需要首先分配一个struct card *块来让它指向:

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;

This call allocates a single block of myDeck->numCards cards:

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

...but a struct card ** is not the appropriate variable to hold a pointer to such a block. You should use just a struct card * for this member, and then use . rather than -> to access each member of this array:

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

The rule to use is that a type * points at a (block of) types. So a struct card * is for pointing at a (block of) struct cards, and a struct card ** points at a (block of) struct card *s.

If you want to use a struct card ** member in your struct, you need to first allocate a block of struct card *s for it to point at:

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

Now you can allocate the cards themselves, putting the pointers to the cards in the array of pointers allocated earlier. The simplest way to do this is one allocation per card:

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

Your reallocation should then look like:

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;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文