How to get Data from a Node Pointing to a function?

Here I have a node, which is pointing to an object, which is pointing to one of the object's functions that returns an int.

 
  current->data->getAmount();


When I debug the code and reach the point where the program tries to return the int I get the error:

Unhandled exception at 0x00B0A0E6 in lab5.exe: 0xC0000005: Access violation reading location 0x00000070.

I'm going to guess I cannot return the int from the function in that way. How can I get this data then?
One of your pointers (either current or data) is not initialized.
I don't quite understand... current and data are initialized. Current points to root, and if root was null it would never go into the while loop. So there root points to data, and that data is an object. The object has a function called getAmount() which returns an int.

1
2
3
4
5
6
7
8
9
10
11
12
13
14

Node *current = root;
	
	while(current != NULL && amt != current->data->getAmount())
	{
		if(amt < current->data->getAmount())
		{
			current = current->left;
		}
		else
		{
			current = current->right;
		}
	}
Last edited on
Yes. From your code it is obvious that current is always not null, but that does not mean that it is initializated properly. Also there is no checks for data. Another possibility is that getAmount() manipulates pointers incorrectly.

Your error clearly states that you tried to dereference invalid pointer. Now you only need to find where this invalid pointer slipped in your program.

If you post whole program we might be able to debug it for you.
The whole program is too large: it consists of 2 classes and a large main. It is also a homework assignment so I don't think I can post the whole thing.

I did however find the error in the assignment. Before the while loop, I checked if current->data == NULL, and I got the exception again. So, the problem is with current->data.

The only function that runs before this inserts a node into the tree. One node has already been inserted into the tree by the time my problem occurs. the code for my insertion is this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
bool Tree::Insert(Item *newData)
{
	if(!Retrieve(newData->getAmount(), newData)) 
// checks if an item with this data already exist in the tree. 
//I passed this line because the tree was empty.
	{
		Node *newNode = new Node;
		newNode->data = newData;
		root = InsertData(root, newNode);
		return true;
	// Print error here
	}
	return false;
}

Tree::Node* Tree::InsertData(Node *current, Node *newNode)
{
	if(current == NULL)
	{
		current = newNode;
	}
	else if(newNode->data->getAmount() < current->data->getAmount())
	{
		current->left = InsertData(current->left, newNode);
	}
	else
	{
		current->right =  InsertData(current->right, newNode);
	}
	return current;
}
Last edited on
where is root was assigned before?
1
2
3
4
Tree::Tree()
{
	root == NULL;
}


So when I constructed a Tree in my main, it was made with a Node root pointing to Null. Then I constructed my tree so far by adding one newNode. Now, pointing to the data of that newNode causes errors.
1
2
3
Node *newNode = new Node;
newNode->data = newData;
root = InsertData(root, newNode);
What do you think newNode->left and newNode->right equals to?
It just points to NULL right?
I suspect the problem is that current->data is NULL.
It just points to NULL right?

Only if Node's default constructor initializes it that way.

I'm also worried about Tree::Insert(). If newData isn't already in the tree then you insert it and the tree takes ownership of it. But if newData is already in the tree then who owns it?
It just points to NULL right?
Nope, you did not write anything to it, so they are pointing to some random memory.
I set the left and right to NULL, and I got the exception.

The line I'm getting the exception on is when I call current->data->getAmount();, and when it gets to the "getAmount()" function in another class. When it's inside that other function, the program crashed when it tries to return an int.
So proble either in data pointer or in getAmount function definition.
I find that if I called current->data->getAmount(); anywhere it doesn't work. Can I even legally do "current->data->getAmount();"? If I was doing something else, like "current->data->amount;" I would have to put it in parenthesis and dereference it to get the "amount": *(current->data->amount). So is there anything I have to do if I'm calling a function?
No, syntax is correct.
Okay, then here is my code where I create the item before inserting it into the tree:

1
2
Item newItem( stoi(line)); // the numbers were in string line, so I converted from string to int
		Tree.Insert(&newItem); // The function to insert in tree takes in a new Item as a pointer so I passed in a reference 


Then we get down to this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
bool Tree::Insert(Item *newData)
{
	if(!Retrieve(newData->getAmount(), newData)) 
// checks if an item with this data already exist in the tree. 
//I passed this line because the tree was empty.
	{
		Node *newNode = new Node;
		newNode->data = newData;
		root = InsertData(root, newNode);
		return true;
	// Print error here
	}
	return false;
}

Tree::Node* Tree::InsertData(Node *current, Node *newNode)
{
	if(current == NULL)
	{
		current = newNode;
	}
	else if(newNode->data->getAmount() < current->data->getAmount())
	{
		current->left = InsertData(current->left, newNode);
	}
	else
	{
		current->right =  InsertData(current->right, newNode);
	}
	return current;
}


I tested seeing what would happen if I tried to access current->data or root->data anywhere, and I always got the exception.
Last edited on
1
2
Item newItem( stoi(line));
Tree.Insert(&newItem);

Again, you need to be clear on ownership of the items. In this case, you're inserting a local variable into a tree structure. As soon as newItem goes out of scope, the tree contains a dangling pointer (pointer to invalid memory). E.g.:
1
2
3
4
5
6
7
{
    Item newItem( stoi(line));
    Tree.Insert(&newItem);
    // newItem gets destroyed. Tree is now corrupt.
}
Item *secondItem = new Item(10);
Tree.Insert(secondItem);
Line 7 will result in undefined behavior as the tree tries to compare secondItem to the now destroyed newItem.
So are what are some ways I can fix this issue? I've only started learning C++ for the last month, and we just got onto trees and nodes, which we are doing at the same time. It is very confusing.
I really have no Idea. I tried putting Account higher up in the program, and storing it in a vector, but it keeps deleting it everytime.
Instead of having Node::data be a pointer to Item, make it an instance of Item. That will actually make most of this go away.
Topic archived. No new replies allowed.