2017-10-27 19 views
-1

この例では、リストの最初の要素を動的に割り当てることができない理由はわかりません。 私は "a"へのポインタを失うので、解決策が悪いと理解しています。私が理解していないのは、その場合、私の関数が空リストを返す理由です。C++の基本的な動的割り当て

要求されたように私は例を単純化しています

ListNode* createList() { 
    //Why not - ListNode* a = new ListNode(0); ? 
    ListNode list(0); ListNode * a = &list; 
    for(int i=0; i < 5; i++){ 
     a->next = new ListNode(0); 
     a = a->next; 
    } 
    //return a->next; 
    return list.next; 
} 
+1

定義されていない動作があります。何かが起こる可能性があります。 – user0042

+0

問題を詳細に教えてください。あなたは「空リスト」とはどういう意味ですか?あなたは何が起こるかを見るために、デバッガのコードを一行ずつ進めようとしましたか?また、[最小、**完全**、および検証可能な例](http://stackoverflow.com/help/mcve)を作成して表示してください。 –

+0

問題をよりよく理解し、マシンで実行できるように、コンパイル可能なコードを提供してください。 – alDiablo

答えて

1

私は最初の要素が動的に割り当てられるようにコードを修正しました。

提案された解決策の問題点は、リストの末尾(つまり空のリスト)へのポインタをがリストの最後に到達したことを返すことでした。

ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { 
if (l1 == NULL && l2 == NULL) return NULL; 
int carry = 0, sum = 0; 
ListNode* a = new ListNode(0); 
ListNode* head = a; 
while(l1 || l2 || carry){ 
    sum = carry; 
    if (l1 != NULL) sum+=l1->val; 
    if (l2 != NULL) sum+=l2->val;  
    carry = sum/10; 
    a->next = new ListNode(sum % 10); 
    a = a->next; 
    l1 = (l1 == NULL) ? NULL : l1->next; 
    l2 = (l2 == NULL) ? NULL : l2->next; 
} 
return head->next; 

}

それがお役に立てば幸いです。あなたはそれを作成するようa->nextはあなたを失敗返す

+0

'ListNode * a =新しいListNode(0);'のリークをどのように処理する予定ですか? – user4581301

+0

リークがあり、それは悪いことに私は同意しますが、私はちょうどソリューションが動的割り当てで実行されるようにしたい – alDiablo

1

a = a->next; 

反復処理するためにリストをので、aは常にリスト内の最後のノードを指しています。あなたがリストを作成し、

return a->next; 

a終了したら、まだリスト内の最後のノードであり、nextはおそらくNULLまたはnullptrです。そうでなければ、あなたは大きな爆弾バグを持っています。返されるリストはなく、この時点でリストの先頭が失われているため、リストは返されません。 Ooops。一方

return list.next; 

あなたはダミーノード上に構築されたリストを作成したダミーのプレースホルダノードの後に​​ノードを返し、これ。 listはローカル変数であるため、自動ストレージ期間があり、範囲外になったときにクリーンアップされます。それが指し示すListNodeのチェーンはすべて動的に割り当てられ、安全に返される可能性があります。

補遺:削除したコードで

、動的

ListNode* a = new ListNode(0); 

aを割り当てることは、これはないが、あなたが、あなたが述べたようにクリーンアップを必要とするの周りぶら下がっaを有する関数の最後に意味しますダングリング・ポインターと呼ばれ、リークと呼ばれています。

あなたは

ListNode* a = new ListNode(0); 
ListNode* start = a; 

以降

return start->next; 

でそれを救うことができますが、あなたがlistで作成した自動バージョンはクリーンアップを必要とせず、少ないが間違って行くことができるので、より良いオプションです。

ダミーノードがまったく存在せず、最初に作成されたノードへのポインタを保持するだけでも、それは別の時間のストーリーです。