我很难引用结构内部的内存,我不确定我的语法是否正确(尽管考虑到其他帖子,我认为我很好)。代码在运行时崩溃。据我所知,我已经分配了所需的内存(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
:
void addCard(struct deck * myDeck)
{
if (!myDeck) {
printf("invalid inputn");
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.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()
)。
Btw:对我来说,转换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 *
指向一个(block of) struct card
s, struct card **
指向一个(block of) struct card *
s。
如果你想在struct中使用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 cardn");
myDeck->numCards--;
return;
}
/* put the data */
myDeck->cards[myDeck->numCards - 1]->number = number;
myDeck->cards[myDeck->numCards - 1]->type = suiteType;