あなたのコードには多くの問題があります:英語で最長の単語を考える
は約30文字で、このサイズの割り当ては単語のためではなくdefintionのために現実的である:
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()
通話だけではなく、1に適用するために使用した修正します!
パー@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);
あなたがランダムにメモリにコピーしているので、あなたがdic
にname
とmean
のための任意の領域を割り当てていなかったとして。
パー@Jarvis、動作しません:
あなたがdic
のコピーをしましたので、元のdic
のsize
がそれと同じになりますaddnewWord()
内部ようにするには、値によってdic
を渡していますコールの前にあった!
メモリリーク:
addNewWord(createNewWord(), d);
あなたは何createNewWord()
にあなたのハンドルを落としそうあなたがメモリを解放することはできません返さそれはmalloc()
「
あなたmalloc()
メモリをdはそれ最終的には自由に何の手段を提供しません。
構造体を値渡しして返すことは、データがそのままコピーされるため、このような状況では災害です。最低でも、上記の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;
}
実行時エラーが何PUN DICTIONARY
> ./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)
>
の作成しますか? forループはどこにありますか?私は1つしか見ることができません。 – dave
すべての関数パラメータは、Cの値によって渡されます。つまり、 'd'の* copy *を' addNewWord'に渡しています。したがって、その関数の 'dic'に対するすべての変更は、呼び出し元の元の' d'変数に影響しません。その結果、同じ 'd.word'が複数回解放されます(したがって、2番目のループのエラー)。 – kaylum
1)一般的に、 'malloc'&friendsや' void * 'の結果をキャストしないでください。 2) 'fflush(stdin)'は_undefined behaviour_を呼び出します。 3)[ask]を参照してください。 – Olaf