2014-09-20 4 views
0

Почему требуется двойной указатель с рекурсией, если я хочу добавить узел в связанный список. Он должен работать с одним указателем.Требуется двойной указатель в рекурсии

Следующий код не работает для меня

class LinkedList 
{ 
private: 
    struct Node 
    { 
     int data; 
     Node* link; 
    }*Ptr; 
public: 
    LinkedList() 
    { 
     Ptr = NULL; 
    } 

    void Add(int num) 
    { 
     /*Add(&Ptr, num);*/ 
     Add(Ptr, num); 
    } 

    void Add(Node* Ptr, int num) 
    { 
     Node* tmp = NULL; 

     if (Ptr == NULL) 
     { 
      tmp = new Node; 
      tmp->data = num; 
      tmp->link = NULL; 
      Ptr = tmp; 
     } 
     else 
     { 
      Add(Ptr->link, num); 
     } 
    } 

    void Display() 
    { 
     Node *tmp; 
     tmp = Ptr; 

     while (tmp != NULL) 
     { 
      cout <<tmp->data << endl; 
      tmp = tmp->link; 
     } 
    } 
} 


int main() { 

LinkedList l; 

    l.Add(10); 
    l.Add(20); 
    l.Add(30); 
    l.Add(40); 
    l.Add(50); 

    l.Display(); 

    _getch(); 
    return 0; 

} 
+0

'PTR = TMP;' не означает * ничего * вызывающему в 'Add() '(и на самом деле происходит утечка памяти). Вы используете параметр 'Ptr' с тем же именем, что и член (' Ptr'), который не помогает (и обычно не рекомендуется). Вам необходимо либо передать указатели, которые будут изменены, либо по ссылке, либо по ссылке. Это C++, вы можете угадать предпочтение (разрешено ли вам использовать их или нет). – WhozCraig

ответ

3

Требуется «двойной указатель», потому что вы изменяете значение указателя внутри функции.

Даже не смотря на свой код, посмотрите на это очень простой пример:

void foo(int *x) 
{ 
    x = new int[10]; 
} 

int main() 
{ 
    int *p = 0; 
    foo(p); 
    // why is p still NULL? 
} 

Вы увидите, что значение p не изменится, даже если функция, очевидно, изменяет параметр, который был принят. Проблема заключается в том, что x является временной переменной, и любые изменения в x уходят после завершения функции.

Чтобы устранить эту проблему, необходимо либо передать указатель на указатель или ссылку на указатель:

void foo(int** x) 
{ 
    *x = new int[10]; 
} 

void foo2(int *& x) 
{ 
    x = new int[10]; 
} 

int main() 
{ 
    int *p = 0; 
    foo(&p); // now p will change 
    delete [] p; 

    p = 0; // try again 
    foo2(p); // p also changes here 
    delete [] p; 
} 
0

Что мне делать, если у меня есть проблемы указателей, (что делали), было сделать это, (особенно со связанными списками) ... Я не запускаю код, но я не полностью могу назвать ваш класс 1 ... И, во-вторых, похоже, что ваш указатель списка всегда находится в последнем элементе списка ... Итак, если он работает, единственный элемент, который он будет читать, является последним ... Попробуйте использовать отладчик и посмотрите на процесс добавления или отображение ...

Смежные вопросы