2011-10-17 77 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