Destructors

Feb 13, 2014 at 9:46am
Guys, Sory if its a silly questionn.I have been trying to fix it for hours now.I get a weired segmentation fault.

Basically, I have a Stack class, It works fine.I then have a Queue class which instantiates a Stack class.So when I create the Queue class I get a segfault.

This is my Queue class.
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
  // this is the queue.cpp

template <class T>
Queue<T> :: Queue()
{
	Stack<T>* stack = new Stack<T>();
//		stack->pop;
}

template <class T>
Queue<T> :: ~Queue()
{
		delete stack;
}


// this is the main I test the queue

//	Stack<int> stack;
	Queue<int > q; // The error occurs here. 
	
/*	stack.push(4);
	stack.push(7);
	stack.push(3);
	stack.push(1);*/
	return 0;
Feb 13, 2014 at 9:47am
this is my Stack Destructor and constructor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

template <class T>
Stack<T> :: Stack()
{
	top = NULL;
}

template <class T>
Stack<T> :: ~Stack()
{
	Node * temp;
	
	while(top != NULL)
	{
		temp = top;
		top = top->next;
		
		delete temp;
		//temp = 0;
	}
}
Feb 13, 2014 at 10:07am
In the Queue constructor you create a temporary variable stack which hides the class variable of the same name, so the actual class variable is uninitialized. The memory allocated in the constructor is leaked, and you attempt to delete memory you don't own in the Queue destructor.
Last edited on Feb 13, 2014 at 10:26am
Feb 13, 2014 at 10:17am
A segmentation fault usually occurs because you try to access memory that you don't own.
You access memory you don't own by using a bad pointer.

In your case, the stack member variable appears to be a bad pointer. Why?
Because in your constructor, you declare a local variable named stack, and you don't change the actual member variable.

1
2
3
4
5
template <class T>
Queue<T> :: Queue()
{
	stack = new Stack<T>();
}


The above constructor can be rewritten to use initialization lists.
(This can only be done for constructors.)

1
2
3
4
template <class T>
Queue<T> :: Queue(): stack(new Stack<T>())
{
}


The benefit of using initialization lists is that the member data is initialized at its construction, instead of being assigned to after its construction. This saves a step, and in some cases can speed up the program.

http://www.parashift.com/c++-faq/init-lists.html
Feb 13, 2014 at 10:53am
thanks guys, The problem was this line.
 
Stack<T>* stack = new Stack<T>();
Feb 13, 2014 at 11:30am
http://www.cplusplus.com/forum/general/112111/


Apart
you've got template function definitions in a source file.
http://www.cplusplus.com/forum/general/113904/#msg622073

¿why and how does a `queue' use a `stack' ?
Feb 13, 2014 at 11:55am
Is there any need to dynamically allocate that Stack object? It's created when the Queue is created, and destroyed when the Queue is destroyed. In other words, its lifetime is exactly the same as the Queue object it belongs to.

Why not simply make the object itself a member of the class, rather than using a pointer and dynamically allocating?

Topic archived. No new replies allowed.