0

char* フィールド (単語) を持つ構造体に新しいノードを追加しようとしています

listT の定義:

enum boolean {false, true};
struct list {
    enum boolean sorted;
    union{
        int words;
        char *word;
    };
    struct list* next;
    struct list* previous;
};
typedef struct list listT;

add_word_node 関数は main によって次のように呼び出されadd_word_node(read_word, list_head)read_wordいます。Word は文字列として渡されますが、strncpy の後には終端バイトがありません。

>Debugger:
     add_word_node (word=0xbffff0fa "ally", head=0x804c038) at prog.c    
>Debugger:
     (gdb) p newnode->word


     $2 = 0x804c068 "allyP\224\373\267\377\377\377\377" 




 listT *add_word_node(char word[], listT *head) {
    listT *newnode;
    listT *curr = NULL;//sorted
    //listT *prev;//sorted

    newnode = malloc(sizeof(listT)); /* allocate new node and check */
    newnode->word = malloc(sizeof(char)* WORDLEN);
    strncpy(newnode->word, word, strlen(word));
    //newnode->word = strndup(word, strlen(word));


    if (newnode == NULL) {
        return (NULL);
    }

    if (head->sorted == false){ //eisagwgh sto telos ths listas
        newnode->next = head;
        head->previous->next = newnode;
        newnode->previous = head->previous;
        head->previous = newnode;
    }else {
        if(head->next == head){
            newnode->next = head;
            newnode->previous = head;
            head->next = newnode;
            head->previous = newnode;

        }else{
            for (curr = head->next; curr->next != NULL; curr = curr->next){//for( curr = head->next; ;){
                if(curr == NULL) break;
                if(strncmp(curr->word,newnode->word,strlen(word)) > 0) break;
                //else curr= curr->next;
            }
            if(strncmp(curr->word,newnode->word,strlen(word))== 0){
                return(curr);
            }
            newnode->next = curr;
            newnode->previous = curr->previous;
            newnode->previous->next = newnode;
            newnode->next->previous = newnode;
        }
    }

    return (newnode);

}

この問題に関する他のトピックをいくつか読み、char* の代わりに word[] を使用するように関数を変更しましたが、それでも機能しません。さらに情報が必要な場合は教えてください。また、strndup を使用すると、エラーなしで動作することがあります。

4

2 に答える 2

0

@Gopiの答えを少し拡張するには:

あなたの声明

newnode = (listT *) malloc(sizeof(listT) + WORDLEN);

ポインタにメモリを割り当てますnewnode。これは、たとえばWORDLENが と同じ場合、 の 2 つの要素にsizeof(listT)メモリを割り当てることを意味します。これは、たとえば、 の 2 つの要素にメモリを割り当てるのと似ています。listTnewnodechar *ptr = malloc(2);charptr

TL;DR: このWORDLENメモリは に割り当てられません。割り当てられnewnode->wordますnewnode。それだけです。newnode->word問題を解決するには、メモリを個別に割り当てる必要があります。newnodeそのメモリは必要ありませんが、必要ですnewnode->word

strndup()メモリが割り当てられるため機能します。

それでもこれを理解するのに苦労している場合は、ポインターについて誤解している可能性があります。

newnode->wordポインタです。特定のマシンでは固定サイズ (8 バイトなど) です。listT簡単にするために、は次のように定義されていると仮定します。

typedef struct {
    char *word;
} listT;

次に、メモリを割り当てるときに、1 つのポインターを保持できるように 8 バイトを割り当てるだけで済みます。newnode次に、そのポインターにメモリを割り当てる必要があります。これは、いくつかの文字を格納するために使用されます。


あなたの問題とは関係ありませんが、 の戻り値をキャストすべきではないことも指摘したいと思いますmalloc()malloc の結果をキャストしますか? を参照してください。

于 2014-12-27T18:38:25.187 に答える
0

あなたが言うようにchar *word、このポインタにはメモリを割り当てる必要があります

newnode->word = malloc(sizeof(char) * (WORDLEN+1)); /* Please access the structure elements accordingly */

何かを書き込む前に、ポインタにメモリを割り当てる必要があります。

于 2014-12-27T18:20:02.317 に答える