memory management

Started by
6 comments, last by fireside 18 years, 10 months ago
The following code compiles with no errors, however, when I run it, I get a segmentation fault (i am running on linux). I have traced the problem back to the actual allocation of memory using operator new. I dont know what is wrong though, here is the code:

//list.h

//list.h

#ifndef GUARD_list.h

#define GUARD_list.h


#include <iostream>


template <class nodeType>
class listNode {
	public:
		nodeType data;
		listNode<nodeType>* next;
};

template <class T>
class list {
	public:
		//default constructor
		list(): first(NULL) { };
		// default destructor
		~list();
		
		// functions to manage data
		// get data from spot
		T get(listNode<T>*);
		//T get();
		
		// print data
		std::ostream& print(std::ostream&, listNode<T>*);
		
		// find data
		listNode<T>* find(T);
		
		// instert element into list or insert element after given position
		T insert(T);
		listNode<T>* insert(T, listNode<T>*);
		
		// remove element from list
		listNode<T>* remove(listNode<T>*);
		
		// print list
		std::ostream& list<T>::print(std::ostream&);
		
	//private:
		listNode<T>* first;
};

template <class T>
list<T>::~list()
{
	while(first != NULL)
	{
		first = remove(first);
	}
}




template <class T>
T list<T>::get(listNode<T>* element)
{
	return element->data;
}

template <class T>
std::ostream& list<T>::print(std::ostream& out, listNode<T>* element)
{
	return out << element->data;
}

template <class T>
listNode<T>* list<T>::find(T valueToFind)
{
	
	listNode<T>* node = first;
	T value;
	while (node != NULL || value != valueToFind)
	{
		value = node->data;
		node = node->next;
		
	}
	
	return node;
}

template <class T>
T list<T>::insert(T value)
{
	// does first equal null
	if (first == NULL)
	cout << "first equals null\n";
	
	
	listNode<T>* node = first;
	if (node == first)
	cout << "node equals first\n";
	
	// find last pointer
	while (node != NULL)
	{
		node = node->next;
	}
	
	std::cout << "here\n";
	node = new listNode<T>;
	std::cout << "memory allocated";
	node->data = value;
	node->next = NULL;
	return node->data;
}
	
template <class T>
listNode<T>* list<T>::insert(T value, listNode<T>* n)
{
	// pointer to node before new element
	listNode<T>*& nodeBefore = n;
	
	// pointer to node after new element
	listNode<T>*& nodeAfter = n->next;
	
	// pointer to new node
	listNode<T>* newNode = new listNode<T>;
	
	// link nodeBefore to newNode
	nodeBefore->next = newNode;
	
	//link newNode to nodeAfter
	newNode->next = nodeAfter;
	
	// set value of newNode
	newNode->data = value;
	
	return newNode;
}

template <class T>
listNode<T>* list<T>::remove(listNode<T>* nodeToRemove)
{
	
	listNode<T>* nodeAfterRemoved = nodeToRemove->next;
	delete nodeToRemove;
	nodeToRemove = nodeAfterRemoved;
	return nodeAfterRemoved;
}

template <class T>
std::ostream& list<T>::print(std::ostream& out)
{
	listNode<T>* node = first;
	while (node != NULL)
	{
		out << node->data << "  ";
		node = node->next;
	}
	out << std::endl;
	return out;
}
#endif   




// linked_list.cpp

#include <iostream>
#include "list.h"

using namespace std;

int main()
{
	list<int> test;
	
	cout << test.insert(7);
	
	
	return 0;
}




Here is what the terminal spits out at me:

[grunewac@tetra LinkedList.dir]% ./linked_list.exe
first equals null
node equals first
here
Segmentation fault (core dumped)
[grunewac@tetra LinkedList.dir]%



[Edited by - xidis on June 22, 2005 12:00:20 PM]
Advertisement
So where's the rest of it?

More accurately, where do you set listNode::next to null? Where in insert() do you actually link the nodes together?
I tested the code you posted in VC2003, and it ran fine.

note:
I did have to make a real destructor for list.

results:
first equals null
node equals first
here
memory allocated7

[Edited by - Rattrap on June 22, 2005 1:59:37 PM]

"I can't believe I'm defending logic to a turing machine." - Kent Woolworth [Other Space]

maybe try this in place of just node = new listNode<T>;

	try	{		node = new listNode<T>;	}	catch(...)	{		std::cout << "New threw an exception" << std::endl;	}

"I can't believe I'm defending logic to a turing machine." - Kent Woolworth [Other Space]

Ok, i posted the rest of the code.

Why do u need a destructor for the node?

Is that why im getting that segmentation fault, or is it because linux stinks?
your find implementation is bugged out...
template <class T>listNode<T>* list<T>::find(T valueToFind){		listNode<T>* node = first;	T value;	while (node != NULL || value != valueToFind) //this is bad mojo	{		value = node->data;		node = node->next;			}		return node;}


Question: What happens if the node var is null and value var does not equal the valueToFind var?
Answer: It crashes because you attempt to access null->data.

fix is
...while(node != NULL && value != valueToFind)...

i haven't checked the rest, but this is one potential cause for your crash.

&& don't blame linux ... blame the linux user :)+)
your welcome
Sorry, there was a little typo in my message, I had to complete the defintion of the list destructor. node: was supposed to be note:. Sorry about that confusion.

"I can't believe I'm defending logic to a turing machine." - Kent Woolworth [Other Space]

I use linux/emacs with a small makefile. The first thing I do after a seg fault is to go to the directory, type rm *.o, then recompile. My makefile isn't good enough to properly recompile all my changes. Other than that, it works perfectly and I only segfault when I'm trying to access something that wasn't allocated. Linux is a fantastic development environment once you get used to it, too bad about the 101 flavors.

[Edited by - fireside on June 22, 2005 3:48:00 PM]

This topic is closed to new replies.

Advertisement