Список ошибок null ptr - PullRequest
0 голосов
/ 11 мая 2018

Это в основной функции. Использование visual studio 2017.

list a;
a.insertAtEnd("i", 1);
a.insertAtEnd("love", 1);

Здесь в основном, когда вызывается вторая вставка в конце. Программа вылетает и говорит, что getnext () имеет значение NULL. Хотя при создании каждого нового узла следующий указатель объявляется NULL.

    class node {
public:
    node(string value) {
        next = NULL;
        data = value;
    }
    void setNext(node *temp) {
        next = temp;
    }
    void setdata(string value) {
        data = value;
    }
    node* getNext() {
        return next;
    }

Отладчик показывает, что эта функция не работает ^

string getData() {
    return data;
}
void createDetail() {
    detail *tmp = new detail();
    d = tmp;
}
void setDetail(int lin) {
    d->insertAtEnd(lin);
}
void getDetails() {
    d->print();
}
private:
    node *next;
    string data;
    detail *d;
};


class list {
public:
    list() {
        head = NULL;
    }
    void insertAtEnd(string, int);
    void insertAfter(string, string);
    void display();
private:
    node *head;
};

void list::insertAtEnd(string value, int lin) { //main func being used
if (head == NULL) {
    node *temp = new node(value);
    temp->createDetail();
    temp->setDetail(lin);
    head = temp;
}
else {
    node *temp2 = head;
    while (temp2->getNext() != NULL || temp2->getData()!=value)
    {
        temp2 = temp2->getNext();
    }
    if (temp2->getData() == value)
    {
        temp2->setDetail(lin); //if same line then increment frequency, dont create new detail as word exists
    }
    else
    {
        node *temp = new node(value);
        temp->createDetail();
        temp->setDetail(lin);
        temp2->setNext(temp);
    }

}
}

1 Ответ

0 голосов
/ 11 мая 2018

In

while (temp2->getNext() != NULL || temp2->getData() != value)
{
    temp2 = temp2->getNext();
}

temp2->getNext() != NULL будет иметь значение NULL для последнего элемента в списке, и данные в последнем элементе в списке могут не соответствовать значению.В этом случае

while (NULL != NULL || "I" != "love") // false or true = true. Enter loop
{
    temp2 = NULL;
}

Следующая итерация заканчивается неудачей, потому что

while (NULL->getNext() != NULL || temp2->getData() != value)
{
    temp2 = temp2->getNext();
}

Ка-блам.

Мое решение сильно меняет код.Тебе это может не понравиться.Также обратите внимание, что я удалил все, что не будет компилироваться, потому что это было исключено.

class node
{
    friend class list; // list has access to node's private members
public:
    node(string value)
    {
        next = NULL;
        data = value;
    }
    // removed setNext. Only list should ever be allowed to set the next member
    void setdata(string value)    {
        data = value;
    }
    // same deal for get. Some shmuck could delete link->getNext();, so why let them?
    string getData()
    {
        return data;
    }
private:
    node *next;
    string data;
};

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

class list
{
public:
    list()
    {
        head = NULL;
    }
    void insertAtEnd(string);
private:
    node *head;
};

Без изменений, кроме удаленного материала, поскольку он поддерживает код, не включенный в вопрос.

void list::insertAtEnd(string value)
{ //main func being used
    node **cur = &head; // double pointer abstracts away need to test for head. 
                        // Now all nodes are equal and we're always pointed at a next.

    while (*cur != NULL && (*cur)->getData() != value) // note && not ||
    //we loop until out of nodes unless we find a match  
    {
        cur = &(*cur)->next; // get pointer to next next 
    }
    if (*cur != NULL) // pointing at a node. Must have exited because of match
    {
        // did stuff I ommtted because no MCVE
    }
    else // not pointing at node. Need a new node.
    {
        *cur = new node(value);
    }
}

Кровавая баня,Вместо того, чтобы бросать большой шар объяснений, я прокомментировал, что я делал и почему.

...