C ++: Хотя цикл не завершится как NULL, я что-то упустил?

Кажется, я не могу понять, почему цикл while не закончится.

Это должно быть пока (ноль) по существу.

Я не могу понять это.

Вся помощь будет оценена: D

Я не знаю, что вообще могло остановить цикл while? Это говорит о том, что первая запись сохраняется, а следующая запись находится в 0x0000000000 и ??? имя и ??? ??? Координаты, так что это на самом деле NULL. Я попытался добавить в конструктор next = 0; вместо next = NULL и все равно не сработало.

Спасибо, парни.

Энтони

EDIT:  Value of nodePtr = 00000000 if next = 0 in the constructor
Value of nodePtr = 00899FE0 if next = NULL in the constructor
if adding a cout << nodePtr->next; before the while.

http://pastebin.com/7usYdfHB — Полная программа для справки.

EDIT2:
http://i.imgur.com/fKCoSjV.png
Это всплывающее окно, когда я иду, чтобы ввести 2-й записи.

void LinkedList::appendNode(string name, double x, double y)
{
ListNode* newNode; // To point to new node
ListNode* nodePtr; // To traverse List

// allocate new node
newNode = new ListNode(name, x, y);

// If no head, head is the newNode
// else traverse the list to find the end and append newNode
if (!head)
{
head = newNode;
cout << "Record inserted successfully.\n" << endl;
}
else
{
nodePtr = head;

//traverse the list loop
while (nodePtr->next) //VS 2012 locks up here <-----
{

//Checks for duplicate entry by name
if (nodePtr->cityName == name)
{
cout << "No need to insert again, as this record exists in the existing data set.\n" << endl;
return;
}
//traverse the list
nodePtr = nodePtr->next;
}
// checks 2nd entry, as while loop wont run for a 2nd entry.
if (nodePtr->cityName == name)                  {
{
cout << "No need to insert again, as this record exists in the existing data set.\n" << endl;
return;
}
}
// if next is NULL add newNode
else if (!nodePtr->next)
{
nodePtr->next = newNode;
cout << "Record inserted successfully.\n" << endl;
}
}

0

Решение

Помимо очевидной утечки памяти при попытке вставить уже существующее имя, ваш код работает нормально. Работает нормально когда либо 0 или же NULL используется для инициализации указателей. Это не имеет значения.

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

Кстати, с помощью дополнительного уровня косвенности вы можете упростить свою сильно разветвленную appendNode функция в значительно более компактный и почти не имеющий ответвлений

void LinkedList::appendNode(string name, double x, double y)
{
ListNode** pnodePtr;

for (pnodePtr = &head; *pnodePtr != NULL; pnodePtr = &(*pnodePtr)->next)
if ((*pnodePtr)->cityName == name)
break;

if (*pnodePtr == NULL)
{
*pnodePtr = new ListNode(name, x, y);
cout << "Record inserted successfully.\n" << endl;
}
else
cout << "No need to insert again, as this record exists in the existing data set.\n" << endl;
}

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

Также (ссылаясь на полную версию кода), в ваших функциях из группы «удалить по координате» вы почему-то проверяете и то и другое x а также y координаты головного узла, но только один координаты других узлов вниз по списку. Зачем? Это довольно странно и, кажется, не имеет особого смысла. Между тем, функции из группы «поиск по координатам» не имеют этой проблемы — они обрабатывают все узлы последовательно.

Также, ваш displayList функция страдает от заблуждения return в самом начале, поэтому он никогда ничего не печатает. Вам нужно добавить пару {} правильно сгруппировать свои высказывания.

1

Другие решения

Я пытался воспроизвести вашу проблему, но не смог. Я пересмотрел ваши классы ListNode и LinkedList. Код ниже работает, может быть, это поможет вам разобраться в вашей проблеме. Я немного изменил его рефакторинг, чтобы упростить его (в дальнейшем вам следует рассмотреть возможность отслеживания конца списка, поскольку это поможет с другими операциями, которые понадобятся вашему списку). Обязательно реализуйте деструктор для вашего класса LinkedList для очистки узлов.

#include <string>
#include <iostream>

using namespace std;

struct ListNode
{
string cityName;
double m_x, m_y;
ListNode* next;

ListNode(string name, double x, double y) : cityName(name), m_x(x), m_y(y), next(nullptr)
{}
};

class LinkedList
{
ListNode* head;
public:
LinkedList() : head(nullptr)
{
}
~LinkedList()
{
}
void LinkedList::appendNode(string name, double x, double y)
{
ListNode* newNode; // To point to new node

// allocate new node
newNode = new ListNode(name, x, y);

// If no head, head is the newNode
// else traverse the list to find the end and append newNode
if (!head)
{
head = newNode;
cout << "Record inserted successfully.\n" << endl;
}
else
{
ListNode *nodePtr = head;
ListNode *prevNode = nullptr;

//traverse the list loop
while (nodePtr)
{

//Checks for duplicate entry by name
if (nodePtr->cityName == name)
{
cout << "No need to insert again, as this record exists in the existing data set.\n" << endl;
return;
}
//traverse the list
prevNode = nodePtr;
nodePtr = nodePtr->next;
}
// if next is NULL add newNode
if (prevNode)
{
prevNode->next = newNode;
cout << "Record inserted successfully.\n" << endl;
}
}
}
};

int main()
{
LinkedList list;

list.appendNode("New York", 1.0, 2.0);
list.appendNode("Boston", 1.5, 2.5);
list.appendNode("Miami", 1.7, 2.7);
list.appendNode("Miami", 1.7, 2.7);
}
1

По вопросам рекламы [email protected]