I'm trying to check if an entity exists in a given linkedlist. This is my code:
bool LinkedList::existByID(int ID)
{
//create node to search through the list
Node * helpNode;
//start it at the top of the list
helpNode = head;
if (head == NULL)
{
return false;
}
//while the item has not yet been found
while ((helpNode->data->indicatedEntity->getID() != ID) && (helpNode->data != NULL))
{
if (helpNode->data->indicatedEntity->getID() == ID)
{
//return true - the data exists
return true;
}
else
//if the data has not been found, move on
helpNode=helpNode->next;
}
//if the data has not been found and the end of the
//list has been reached, return false - the item does
//not exist
return false;
}
From the line I marked as the "problem line", the part of the if statement
(helpNode->data != NULL)
I get error CXX0017 (symbol "" not found) and error CXX0030 (expression cannot be evaluated).
This code works if there are no entities in the linkedlist - in other words, if the head is null.
The Node constructor looks like this:
LinkedList::Node::Node()
{
next=NULL;
data=NULL;
}
I've also tried it with the line:
(helpNode != NULL)
and Node constructor
LinkedList::Node::Node(){}
All combinations return the same errors. Any suggestions?
Firstly I recommend fixing a few things with your code.
In your loop you check the data member of helpNode before testing to see if helpNode is actually valid. Imagine you are on the last node - and at the end of the while the following executes - now what gets checked at the top?
helpNode=helpNode->next;
Secondly, once you've checked for helpNode, next you should check that data is valid before checking attributes of data, what if data is NULL?
And now think about what your loop is checking, it's checking that getID() != ID, and yet inside the loop you are testing for the ID, getID() == ID? does that make sense?
I recommend that in your loop, you just check that the next node and data exists, and then within the loop check that the ID matches, and return if true.
Well the line
while ((helpNode->data->indicatedEntity->getID() != ID) && (helpNode->data != NULL))
might be a problem if data is NULL, because then you would be trying to access NULL->indicatedEntity
further if indicatedEntity is NULL, then you are trying to access NULL->getID()
you can rewrite it to
while (helpNode->data != NULL && helpNode->data->indicatedEntity != NULL && helpNode->data->indicatedEntity->getID() != ID)
which doesnt look nice, but it does ensure your pointers are not null before trying to access them.
Related
I've created some chain-like structure, where one object has pointers to the next and previous object of a chain. The code below loops through entire chain, looks for value specified in arguments and removes matching element (if exists).
void List::removeElementByValue(int value)
{
ListMember* nextElem = this->firstValue;
while (nextElem) {
if (nextElem == NULL || nextElem == nullptr) {
break;
}
if (nextElem->value == value) {
if (nextElem->prevValue)
(nextElem->prevValue)->nextValue = nextElem->nextValue;
if (nextElem->nextValue)
(nextElem->nextValue)->prevValue = nextElem->prevValue;
delete nextElem;
this->count--;
return;
}
nextElem = nextElem->prevValue;
}
}
The problem is: I'm getting this error when I'm trying to remove non-existent value from chain.
Exception thrown: read access violation. nextElem was 0xCDCDCDCD.
Function should do nothing in that case. It happens at this line:
if (nextElem->value == value) {
As you see, I've used multiple ways to check if nextElem is correct, but I'm still getting this error. Any ways I can prevent that?
if (nextElem == NULL || nextElem == nullptr)
This will always be false when while (nextElem) is true.
nextElem = nextElem->prevValue;
This needs to use nextValue instead of prevValue.
But, most importantly, you are not updating this->firstValue if the value is found in the first element of the list, so you end up deleting the firstValue and leave it pointing at invalid memory.
Try this instead:
void List::removeElementByValue(int value)
{
ListMember* elem = this->firstValue;
while (elem) {
if (elem->value == value) {
if (elem->prevValue)
elem->prevValue->nextValue = elem->nextValue;
if (elem->nextValue)
elem->nextValue->prevValue = elem->prevValue;
// ADD THIS!!!
if (elem == this->firstValue)
this->firstValue = elem->nextValue;
delete elem;
this->count--;
return;
}
elem = elem->nextValue; // NOT prevValue!
}
}
A better solution is to not implement a linked list manually in the first place. Use the standard std::list container instead, let it do all of the hard hard for you.
#include <list>
class List
{
private:
std::list<int> values;
...
};
...
#include <algorithm>
void List::removeElementByValue(int value)
{
auto iter = std::find(values.begin(), values.end(), value);
if (iter != values.end())
values.erase(iter);
}
I am building essentially a linked lists that can travel in 4 different directions. The vital concepts are as follows:
Node is a class in this scenario, with four Node pointers as class members.
Data and Coordinates are also classes. Data is simply data that the node will contain.
raw_coordinates are the coordinates that the new node should have.
Position is the coordinates of the current node.
moveNorth, moveSouth, moveEast, and moveWest return a new coordinate that reflect a change in position. For example, the position node might have coordinates (0,0). moveNorth takes the position and returns (0,1).
Lastly I would like to state that I am not concerned with the child node not point to the parent node. (i.e not interested if the node, node->north, has a valid node->south that returns to the previous node).
The issue is that my function returns null. Here is my code:
Node* Map::insertNode(Node *node, Data raw_data, Coordinates raw_coordinates, Coordinates position)
{
if (node == NULL)
{
if (compare_coordinates(raw_coordinates, position))
{
return (newNode(raw_data, raw_coordinates));
}
else
{
return node;
}
}
else
{
if (insertNode(node->north,raw_data, raw_coordinates, moveNorth(position)) != NULL)
{
node->north = insertNode(node->north, raw_data, raw_coordinates, moveNorth(position));
}
else if (insertNode(node->south,raw_data, raw_coordinates, moveSouth(position)) != NULL)
{
node->south = insertNode(node->south, raw_data, raw_coordinates, moveSouth(position));
}
else if (insertNode(node->west, raw_data, raw_coordinates, moveWest(position)) != NULL)
{
node->west = insertNode(node->west, raw_data, raw_coordinates, moveWest(position));
}
else if (insertNode(node->east, raw_data, raw_coordinates, moveEast(position)) != NULL)
{
node->east = insertNode(node->east, raw_data, raw_coordinates, moveEast(position));
}
return node;
}
}
I would hazard a guess that your if (node == null) branch isn't working how you intended.
Assuming that compare_coordinates returns true if the current position is "where you need to be", you'll immediately return a new node. This doesn't add the new node into the mesh you're building, so the next time you try to get to that node, it'll be generated again.
Similarly, if compare_coordinates returns false, it looks like you're just giving up the search - the approach I believe you had in mind would likely add a new "empty" node at the current location, then recurse on that node with the current parameters to "get to where you need to be".
All speculation, as there's no comments and explanations of vital parts of the code are missing, but this would result in your grid never expanding beyond a single central node, which could cause null-pointer dereferences causing segfaults.
I wrote this program, and it crashes when I compile. It says the executable has stopped working and Windows is trying to find a solution. I believe the issue is somewhere in this addPage function I wrote to add a node to a linked list, but I'm not sure what is causing the issue.
void initPage(struct page *head, string programName) {
// Assign Properties of the First Node in the Linked List
head->programName = programName;
head->nextPage = NULL;
}
void addPage(struct page *head, string programName) {
// Initialize First Page if Not Initialized
if (head == NULL) {
initPage(head, programName);
return;
}
// Setup the New Page
page *newPage = new page;
newPage->programName = programName;
newPage->nextPage = NULL;
// Set the Pointer to the Beginning of the Linked List
page *current = head;
// While Traversing the Linked List
while(current) {
// If the End of the List is Reached, Append the Page
if (current->nextPage == NULL) {
current->nextPage = newPage;
return;
}
// Grab the Next Page (If not at the End of the Page)
current = current->nextPage;
}
}
This:
if (head == NULL) {
initPage(head, programName);
passes a null to initPage, which then immediately dereferences it. Boom.
Tip: ALWAYS check a pointer for null before using it.
Also, initPage is an incomplete copy of code in addPage. It seems better to always run the code in addPage that creates the new page (i.e., don't call initPage() at all) and then, once you've got a page, test head for null to see if you should just set head to the new page or iterate the list looking for the end.
Im having trouble with this method im trying to get to work. My assignment is to delete the first occurance of an element. It works fine when there is a element to delete in the list. But if i search for an element that is not in the list, it throws me a nullpointer exception on my while loop.
Cant seem to find the problem, i want the loop to stop after: either found element or when temp.next == null(aka at the end of the list).
Can someone point me in the right direction please?
public void deleteFirstOccurance(int data)
{
Node temp = head;
boolean foundElement = false;
if(head==null) //Sjekker om listen inneholder elementer
{
System.out.println("There are no elements in list");
}
else
{
if(temp.element==data) //Sjekker første node
{
head = temp.next;
System.out.println(temp.element+" is deleted");
elementCount--;
foundElement = true;
}
else
{
while(temp.next != null || temp.next.element != data) //Leter fra node sin next frem til den finner data eller treffer null
{
temp = temp.next;
}
if(temp.next.element == data)
{
System.out.println(temp.next.element+" is deleted");
temp.next= temp.next.next;
elementCount--;
foundElement = true;
}
}
}
if(!foundElement)
System.out.println("No elements found");
}//Oppgave3
The exception is thrown, because you are getting the value of temp.next.element before checking if temp.next is null.
The same thing after while loop finishes: you have if (temp.next.element == data) but temp.next may be null here. At this point it is either the next element is the one you are looking for, or null. So a check if (temp.next != null) should suffice.
Also the condition should have &&, not ||: you want to continue the loop, while you have a next element and this element is not what you are looking for.
So to fix the issues, replace while(temp.next.element != data || temp.next != null) with while (temp.next != null && temp.next.element != data), and replace if (temp.next.element == data) after the while loop with if (temp.next != null)
I am writing a program that adds, deletes, and displays nodes (that are doubly linked) and their components, but whenever I try to retrieve a node and display it's components I get this error:
2 [main] a 4640 exception::handle: Exception: STATUS_ACCESS_VIOLATION
2875 [main] a 4640 open_stackdumpfile: Dumping stack trace to a.exe.stackdump
I have narrowed it down to the search function within my .h file that is supposed to search to see if there is a node within the linked list that account number being searched. The function returns the node that comes before it, or the "previous" node.
Here is my search function:
bool searchListByAcctNum (int searchKey, nodePtr *prevOut)
{
bool found = false;
nodePtr p = headNum;
nodePtr prev = NULL;
while (p != NULL)
{
if (p->acctNum < searchKey)
{
prev = p;
p = p->nextNum;
}
else
{
if (p->acctNum == searchKey)
found = true;
p = NULL;
}
}
*prevOut = prev;
return found;
If anyone could help me at all, I'd appreciate it!
It looks like your list may be corrupted, or the pointer you're passing to receive the previous node is invalid, since that code looks okay. However, it seems to me that it could be written in a much simpler manner:
bool searchListByAcctNum (int searchKey, nodePtr *prevOut) {
/// Start at beginning of list, use pointer variable to hold previous.
nodePtr p = headNum;
*prevOut = = NULL;
// Process entire list, will exit early if need be.
while (p != NULL) {
// If past it, just return false, caller should ignore prevOut.
if (p->acctNum > searchKey)
return false;
// If equal, return true, prevOut holds previous or NULL if found at start.
if (p->acctNum == searchKey) {
return true;
// Save previous and advance to next.
*prevOut = p;
p = p->next;
}
// Reached end of list without finding, caller should ignore prevOut.
return false;
}