Почему я получаю ошибку сегментации при реализации связанного списка? - PullRequest
0 голосов
/ 10 июля 2019

В этой функции я получаю ошибку сегментации.Я думаю, что это как-то связано с распределением памяти.Какую ошибку я делаю?

Теперь, если я инициализирую Node * a = NULL, я получаю указатель на мою голову как NULL в конце.

struct Node {
    int data;
    struct Node* next;
    Node(int x) {
        data = x;
        next = NULL;
    }
};

Node* addTwoLists(Node* first, Node* second) {
    // Code here
    Node *a;
    Node *head = a;
    int bor = 0;
    while(first->next && second->next) {
        int ans = first->data + second->data;
        a = new Node((ans%10)+bor);
        bor = ans/10;
        a=a->next;
        first = first->next;
        second = second->next;
    }
    return head;
}

Ответы [ 4 ]

6 голосов
/ 10 июля 2019
  1. a неинициализирован.Вы не должны использовать a, пока не назначите значение
  2. , которое вы никогда больше не назначите для head, поэтому оно никогда не может быть чем-либо еще.
1 голос
/ 10 июля 2019

Для начала переменная head имеет неопределенное значение и не изменяется в функции.

Node *a;
Node *head = a;

Изменение переменной a не означает изменение значения выражения a->next.

// ...
a = new Node((ans%10)+bor);
//...
a=a->next;

Функция может быть записана следующим образом (без тестирования)

Node * addTwoLists( const Node *first, const Node *second ) 
{
    const int Base = 10;

    Node *head = nullptr;

    int bor = 0;

    Node **current = &head;

    for ( ; first != nullptr && second != nullptr; first = first->next, second = second->next )
    { 
        int sum = first->data + second->data + bor;
        *current = new Node( sum % Base );
        bor = sum / Base;
        current = &( *current )->next;
    }

    if ( bor )
    {
        *current = new Node( bor );
    }

    return head;
}

Вот демонстрационная программа

#include <iostream>

struct Node 
{
    explicit Node( int data, Node *next = nullptr ) : data( data ), next( next )
    {
    }

    int data;
    Node *next;
};

void push_front( Node **head, int x )
{
    *head = new Node( x, *head );
}

Node * addTwoLists( const Node *first, const Node *second ) 
{
    const int Base = 10;

    Node *head = nullptr;

    int bor = 0;

    Node **current = &head;

    for ( ; first != nullptr && second != nullptr; first = first->next, second = second->next )
    { 
        int sum = first->data + second->data + bor;
        *current = new Node( sum % Base );
        bor = sum / Base;
        current = &( *current )->next;
    }

    if ( bor )
    {
        *current = new Node( bor );
    }

    return head;
}

std::ostream & display_list( const Node *head, std::ostream &os = std::cout )
{
    for ( ; head != nullptr; head = head->next )
    {
        os << head->data << ' ';
    }

    return os;
}

int main()
{
    const int N = 10;
    Node *list1 = nullptr;
    Node *list2 = nullptr;

    for ( int i = 1; i < N; i++ ) push_front( &list1, i );
    for ( int i = N; --i != 0; ) push_front( &list2, i );

    display_list( list1 ) << '\n';
    display_list( list2 ) << '\n';

    Node *list3 = addTwoLists( list1, list2 );

    display_list( list3 ) << '\n';
}

Ее вывод

9 8 7 6 5 4 3 2 1 
1 2 3 4 5 6 7 8 9 
0 1 1 1 1 1 1 1 1 1     
1 голос
/ 10 июля 2019

Это не распределение, это использование указателя, что все неправильно.

Вот как это должно выглядеть. Этот код поддерживает переменную last, которая является последним узлом, добавленным в список. Вам нужна эта переменная, чтобы вы могли в конце списка. Вы явно пытались сделать это самостоятельно, но неправильно поняли логику.

Node* addTwoLists(Node* first, Node* second) {
    Node *last = NULL;
    Node *head = NULL;
    int bor = 0;
    while(first->next && second->next) {
        int ans = first->data + second->data;
        Node* a = new Node((ans%10)+bor);
        if (head == NULL) {
            head = last = a; // first node, update head and end of list
        }
        else {
            last->next = a; // add a to the end of the list
            last = a;       // update the end of the list
        }
        bor = ans/10;
        first = first->next;
        second = second->next;
    }
    return head;
}

Непроверенный код.

0 голосов
/ 10 июля 2019

Здесь вы можете получить ошибку сегментации по разным причинам.

  1. Если first или second равно NULL , то вы получите ошибку сегментации.Поэтому убедитесь, что если эти два узла не NULL .
  2. Вы не инициализировали a.Поэтому сначала инициализируйте его.

И, как вы хотите, head переменная должна содержать начальный узел списка ответов, поэтому вам необходимо назначать узел всякий раз, когда вы получаете начало списка.

Просто добавьте эту строку после a = new Node((ans%10)+bor);

if(head == NULL) head = a;
...