你的代碼有很多問題:
鑑於在英語中最長的單詞大約是30個字符,這個大小分配是現實的話,而不是把定義:
newword.name = (char*)malloc(30*sizeof(char));
newword.mean = (char*)malloc(30*sizeof(char));
這使得小明顯的感覺:
dic.size = 0;
dic.word = (Words*)malloc(dic.size*sizeof(Words));
你叫零malloc()
!你只能在以後的realloc()
下倖免。即使是故意的,它確實值得評論。
這並沒有真正的工作爲fflush()
是輸出流:
fflush(stdin);
見:How to clear input buffer in C?而且不管修復使用有權申請都scanf()
呼叫,而不只是一個!
每@Jarvis,這不起作用:
dic.word = (Words*)realloc(dic.word,dic.size*sizeof(Words));
strcpy(dic.word[dic.size-1].name, newword.name);
strcpy(dic.word[dic.size-1].mean, newword.mean);
因爲你沒有爲name
和mean
在dic
所以你複製到隨機內存分配任何空間。
每@Jarvis,不工作:
你傳遞dic
的值,因此內部addnewWord()
你已經的dic
副本,以便原始dic
的size
將是相同的,因爲它在電話會議之前!
內存泄漏:
addNewWord(createNewWord(), d);
你把你的手柄上有什麼createNewWord()
回到這樣你就可以永遠釋放它malloc()
「內存ð
您malloc()
的內存,但沒有提供手段,最終釋放它。
隨着數據不斷被複制,按值傳遞和返回結構是一種災難。至少它效率低下,最壞的情況是像上面size
這個問題。而不是冒險,假裝他們只能通過指針傳遞和返回,你會安全地玩,並獲得更好的結果。
下面是你的代碼的返工(在C)與修正,風格的調整和嘗試一致的術語。它也提供一些最起碼的測試代碼,並釋放你的數據的能力:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_WORD_LENGTH 30
#define MAX_DEFINITION_LENGTH 1024
typedef struct entry {
char *word;
char *definition;
} Entry;
typedef struct dictionary {
Entry *entries;
int num_entries, max_entries;
} Dictionary;
Dictionary *createNewDictionary() {
Dictionary *dictionary = malloc(sizeof(*dictionary));
dictionary->num_entries = 0;
dictionary->max_entries = 1;
dictionary->entries = calloc(dictionary->max_entries, sizeof(*dictionary->entries));
return dictionary;
}
void freeEntry(Entry *entry) {
free(entry->word);
free(entry->definition);
free(entry);
}
void freeDictionary(Dictionary *dictionary) {
for (--dictionary->num_entries; dictionary->num_entries >= 0; --dictionary->num_entries) {
// we can't call freeWord() here -- why.
free(dictionary->entries[dictionary->num_entries].word);
free(dictionary->entries[dictionary->num_entries].definition);
}
free(dictionary->entries);
free(dictionary);
}
void purgeInput() {
int c;
while ((c = getchar()) != '\n' && c != EOF) { }
}
Entry *requestNewEntry() {
Entry *entry = malloc(sizeof(*entry));
entry->word = malloc(MAX_WORD_LENGTH);
entry->definition = malloc(MAX_DEFINITION_LENGTH);
printf("============================\n");
printf("Enter word: ");
scanf("%[^\n]", entry->word);
purgeInput();
printf("\nEnter definition: ");
scanf("%[^\n]", entry->definition);
purgeInput();
return entry;
}
void addNewEntry(Entry *entry, Dictionary *dictionary) {
if (dictionary->num_entries == dictionary->max_entries) {
dictionary->max_entries *= 2;
dictionary->entries = realloc(dictionary->entries, dictionary->max_entries * sizeof(*dictionary->entries));
// check if realloc returns NULL and if so, handle the error.
}
dictionary->entries[dictionary->num_entries].word = strdup(entry->word);
dictionary->entries[dictionary->num_entries].definition = strdup(entry->definition);
dictionary->num_entries++;
}
int main() {
Dictionary *d = createNewDictionary();
for (int i = 0; i < 3; i++) {
Entry *e = requestNewEntry();
addNewEntry(e, d);
freeEntry(e);
}
printf("\nRead: ");
for (int i = 0; i < d->num_entries; i++) {
printf("%s (%lu chars) ", d->entries[i].word, strlen(d->entries[i].definition));
}
printf("\n");
freeDictionary(d);
return 0;
}
創建潘詞典
> ./a.out
============================
Enter word: silkworm
Enter definition: Two silkworms had a race but ended up in a tie.
============================
Enter word: horse
Enter definition: A horse is a stable animal.
============================
Enter word: termite
Enter definition: A termite walks into a pub and asks, "Is the bar tender here?"
Read: silkworm (47 chars) horse (27 chars) termite (62 chars)
>
什麼是運行時錯誤? 「第二」循環在哪裏?我只能看到一個。 – dave
所有函數參數都以C的值傳遞。這意味着您將'd'的*副本*傳遞給'addNewWord'。因此,在該函數中'dic'的所有修改都不會影響調用者的原始'd'變量。結果是相同的'd.word'被多次釋放(因此第二個循環出現錯誤)。 – kaylum
1)一般不要投放'malloc'和朋友或'void *'的結果。 2)'fflush(stdin)'調用_undefined behaviour_。 3)見[問]。 – Olaf