tags:

views:

264

answers:

3

Consider the following list:

[LinkNode * head -- LinkNode * node1 -- LinkNode * node2]

I'm creating a stack of FIFO. I Call pop() which I want to pop node1.

LinkNode::LinkNode(int numIn) {
    this->numIn = numIn;
    next = null;
}
.
.
.
int LinkNode::pop() {
    Link * temp = head->next;
    head = temp->next;
    int popped = head->nodeNum;
    delete temp;
    Return numOut;

Question:
1) head should be a pointer or a LinkNode *?
2) Link * temp is created on the call stack and when pop finishes doesn't temp delete automatically?
3) My major confusion is on what is the value of temp->next? Does this point to node1.next which equals node2?

Appreciate your help?

My reference is C++ for Java Programmers by Weiss.

A: 
  1. LinkNode * is a pointer. So I'm not sure what you are asking.
  2. The variable goes out of scope but this does not automatically remove the dynamically allocated data. In C++, if you dynamically allocate data (call new) you need to free it (call delete)
R Samuel Klatchko
In other words, head is initialized as such:LinkNode * headwhich would make it another node. So, head->next would equal node1 but I want to get the value of node1-next which is node2. I'm having difficultly applying the syntax to the concept. Thanks.
JDragon314159
@JKid314159 - you need to distinguish between pointers and nodes. Normally, `head` would point to the first node (so `head->nodeNum` come from the first node) while `head->next` would point to the second node (so `head->next->nodeNum` comes from the second node).
R Samuel Klatchko
Very good. Thank you.
JDragon314159
+1  A: 

It is often useful when implementing linked lists, trees, or other linked data structures to separate the implementation into an encapsulating object (LinkedList, Tree, etc.) and a node object (LinkedListNode, TreeNode, etc.), which allows one to implement methods outside of the actual nodes in question. A problem with popping from the node is that the popped node becomes invalid. Encapsulating the nodes in some larger datastructure allows that datastructure to perform the pop externally, removing the old node.

Another thing to consider is how pop will behave if there are no items left to pop. Should it throw an exception? Should it simply result in undefined behavior?

In a typical linked list, the encapsulating class typically maintains a pointer to the first element, an integer count of the number of elements, and optionally a pointer to the last element (for constant time insertion to the end of the list). For implementing a stack, you only need a single pointer to the front of the list.

Local variables are destructed automatically; however, it is your pointer that is a local variable, not the item to which it is pointing. The item pointed to by your pointer will not be deallocated without an explicit delete.

In your pop code, you are actually removing one too many items. It should be:

int result = head->nodeNum; // extract the result
LinkNode* tmp = head; // save this so we can delete it
head = head->next; // move the head forward to the next item
delete tmp; // deallocate previous head
return result;

Also, don't forget to check that head is non-null before attempting to pop.

Michael Aaron Safyan
I'm stuck onhead = head->nextWouldn't this just equal node1 since head is LinkNode * head with an int value and field LinkNode * next. So, head->next points to node1. Little mixed up here please.
JDragon314159
@JKid, each node's next pointer should point to the next node in the list. The head pointer points to the first node in the list. So, head->next points to the second element of the list. Thus, head = head->next takes the current second element and makes it the first element. The other code ensures that the old first element (which is now no longer in the list) is properly deallocated, and that the contents of the old first element are returned.
Michael Aaron Safyan
After you move head to the next node, which is node2, tmp is now pointing to node1. In other words, the pointer, temp, is pointing to the memory address of node1. The call "delete tmp" deletes tmp. Previous to this call could one have the call "delete *tmp" to delete the object which tmp is pointing to? The call "delete tmp" removes the reference to node1 but doesn't delete node1? Node1 is pointing to node2? Mixed up here???
JDragon314159
@JKid314159, the expression "delete p" invokes the destructor of the object pointed-to by p and deallocates the memory pointed-to by p. It does not deallocate the pointer p itself (keep in mind that p is just an address and the storage for holding that address, i.e. p, may be located on the stack, in which case that wouldn't make sense).
Michael Aaron Safyan
JDragon314159
A: 

Good reference with pictures here. Very good visuals.

http://richardbowles.tripod.com/cpp/linklist/linklist.htm

JDragon314159