0

奇妙な問題があります。私はこのコードを持っていますが、うまくいきません。奇妙な部分は、関数内でリストが変更されることです (printf コマンドはこれを示します) が、この関数を呼び出すと、リストには何も追加されません (私のリストは空ではありません)。

void pushToList(node* list, int val) {
    node* newNode = (node*) malloc(sizeof(node));
    newNode->value=val;

    newNode->next = list;
    list = newNode;

    printf("here, list->value = %d \n", list->value);
    printf("here, list->next->value = %d \n", list->next->value);
}

// ----------------------------------    
//    if (list==NULL) {
//        newNode->next = NULL;
//        list = newNode;
//    } else {
//        newNode->next = list;
//        list = newNode;        
//    }            

たとえば、メイン関数でこの関数を次のように呼び出します。

node* node1;
pushToList(node1, 1111);

そして、ここに別のヘッダー ファイル (関数ファイルに含めたもの) の構造体と typedef があります。

#ifndef STACKELEMENT_H
#define STACKELEMENT_H

struct stackElement {
    int value;
    struct stackElement* next;
};

typedef struct stackElement node;
#endif  /* STACKELEMENT_H */

別の奇妙な動作は、アイテムを追加するための次の関数があることです。この関数は、リストが空でない場合にのみ機能します。

int appendtoList(node* head, int val) {

    node* current = head;
    node* newNode = (node*) malloc(sizeof (node));

         if(newNode == NULL){
            fprintf(stderr, "Unable to allocate memory for the new node\n");
            exit(-1);
        }

    newNode->value = val;
    newNode->next = NULL;

    while (current->next) {
        current = current->next;
    }
    current->next = newNode;

    //    if (head->next == NULL) {                
    //        head->next = newNode;
    //    } else {                
    //        while (current->next != NULL) {
    //            current = current->next;
    //        }
    //        current->next = newNode;
    //    }
    //
        return 0;
}
4

2 に答える 2

1

関数の引数の型として node**list を使用します。

u が struct node *x のような関数へのポインターを void max (struct node*p) に渡すとき。ポインターは値で渡され、かつ、x が指す内容を実際に操作して struct node** を引数の型として使用し、&x を関数に渡したい場合。

同じロジックが問題に適用されるはずです。

于 2013-09-14T14:57:17.313 に答える
0

問題は戻り値の型、つまりこの場合はポインター変数である変数のスコープにありました。mbratch さんからも指摘がありました、ありがとうございましたが、実は mbratch さんのコメントを読む前にふと、「call by value/call by 」とは違うと思う「オブジェクトへの有効期間外へのアクセス」に関する講義ノートのポイントを思い出しました。参照」の問題。この問題に遭遇して混乱する可能性がある人のためのいくつかの説明:関数pushToList内の構造体newNode にメモリを割り当てているため(動的メモリ割り当てコマンドを使用していても)、この変数に割り当てられたメモリは解放/破棄されます。関数が終了したときそして制御は呼び出し先関数 (この場合は main()) に戻ります。したがって、関数の戻り値の型を node* (ノード構造体へのポインター) に設定し、関数でheadを返す必要があります。このような:

node* pushToList(node* head, int val) {
    node* newNode = (node*) malloc(sizeof(node));
    newNode->value=val;
    newNode->next = head;
    head = newNode;     
    return head;
}

appendToList関数では、この間違いに加えて、 mbracthが指摘したように、head自体 (NULL かどうかを確認するため) ではなく、head->next (暗黙的ではありますが) をチェックすることで別の間違いを犯していました: head が NULL の場合、できませんhead->next にアクセスします。実際、stackoverflow に関する他のいくつかの投稿で正解としてマークされた 2 つの回答が、この間違いに私を誤解させました。とにかく、ここに正しい方法があります:

        if (head == NULL) {
            head = newNode;
        } else {                
            while (current->next != NULL) {
                current = current->next;
            }
            current->next = newNode;
        }
于 2013-09-14T14:56:53.057 に答える