2011-10-17 247 views
0

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

Loo王越接近人们意识到,你显然不知道如何安排你的数据... ;-)

此行

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

应分配的指针数组这是项则依次为每卡应该得到的内存assigend。

因此有两个错误:

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 *它与任何指针兼容。

无论如何,类型转换通常不是好主意,因为它可以防止编译器指向某些可能不适合的方式。

+0

非常感谢你为深入解释!非常帮助我! – shleim

0

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

0

此调用分配的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 cards,并且struct card **指向(块)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; 
+0

好吧,但让我说我被迫“使用'结构卡**'(因此指向指针)。你会以不同于我在上面实现的方式实现它吗? – shleim

+0

@shluvme:是的。如果你使用'struct card **',那么你实际上拥有一组指向卡片的指针,而不是一组卡片。这意味着你必须分配一块指针*和*自己分配这些卡片 - 我已经更新了我的答案以表明这一点。 – caf

+0

非常感谢你!事实上,这就是我最终做的,它做的工作:) – shleim