Tell me more ×
Stack Overflow is a question and answer site for professional and enthusiast programmers. It's 100% free, no registration required.

I've been working for a couple of hours now trying to get an Stack based on an Array built and implemented. I have checked several sources and it looks like my ArrayStack class is constructed properly. However, when I run debug, 'head' stays null and size & sp go back to 0: therefore, nothing is actually getting pushed on the stack. Can someone help me understand what I have implemented incorrectly?

Here is my ArrayStack class:

public class ArrayStack <T>{
    protected int sp; //empty stack
    protected T[] head; //array
    private int size;

    @SuppressWarnings("unchecked")
    public void stack(T t){
        sp = -1;
        size = 24; //sets the default size of the stack
        head = (T[]) new Object [size];
    }
    public boolean isFull(){
        return sp == -1;
    }
    public void push (T t){
        if (!isFull())
            head[++sp] = t;
    }
    public T pop (){
        if (isFull()){
            return null;
        }
        else 
            return head[sp--];  //LINE 30
    }
}

Here is my Main Method:

public class StacksAndQsMain {

    public static void main(String[] args) {
        //Array Implementation
        ArrayStack<String> as  = new ArrayStack<String>();

        String s = "Hello";
        String s1 = "World";
        String s2 = "Again";

        as.push(s);
        as.push(s1);
        as.push(s2);

        System.out.println (as.pop()); //LINE 15
        System.out.println();
        System.out.println (as.pop());
        System.out.println();
        System.out.println (as.pop());
        System.out.println();
    }

}

Lastly, here is my stack trace:

Exception in thread "main" java.lang.NullPointerException
at stackAndQs.ArrayStack.pop(ArrayStack.java:30)
at stackAndQs.StacksAndQsMain.main(StacksAndQsMain.java:15)

My variables at public void push (T t)

this       ArrayStack<T>  (id=17)   
head       null 
size       0    
sp     0    
t      "Hello" (id=18)
share|improve this question
add comment

4 Answers

up vote 1 down vote accepted

I noticed two things.

First as others have mentioned you needed to create a constructor and initialize the array. Second, the isFull method should check that sp != this.size -1, basically making sure your not at the 24 element limit of your stack implementation. After changing, isFull you should negate the if conditional in the push method to check that the stack is not full. Also, I would remove the check on the pop method to check if the stack isFull, why prevent someone from popping an element just because the stack is full? Instead check that the stack is not empty.

public class ArrayStack<T> {
    protected int sp; // empty stack
    protected T[] head; // array
    private int size;

    @SuppressWarnings("unchecked")
    public ArrayStack() {
        sp = -1;
        size = 24; // sets the default size of the stack
        head = (T[]) new Object[size];
    }

    public boolean isFull() {
        return sp == this.size -1;
    }

    public boolean isEmpty() {
        return sp == -1;
    }

    public void push(T t) {
        if (!isFull())
            head[++sp] = t;
    }

    public T pop() {
        if (isEmpty()) {
            return null;
        } else
            return head[sp--]; // LINE 30
    }

    public static void main(String[] args) {
        // Array Implementation
        ArrayStack<String> as = new ArrayStack<String>();

        String s = "Hello";
        String s1 = "World";
        String s2 = "Again";

        as.push(s);
        as.push(s1);
        as.push(s2);

        System.out.println(as.pop()); // LINE 15
        System.out.println();
        System.out.println(as.pop());
        System.out.println();
        System.out.println(as.pop());
        System.out.println();
    }
}
share|improve this answer
 
Thank you for your time and explanation! I was just staring to Google the isFull() to find out what I was missing. Greatly appreciated! –  Christopher Day Mar 14 at 0:54
 
@ChristopherDay Glad I could help. –  Kevin Bowersox Mar 14 at 0:57
add comment

You are using the default constructor for the class, which will initialize all of the data members to their default values:

public class ArrayStack <T>{
protected int sp; //empty stack  <-- initialized to 0
protected T[] head; //array <-- initialized to null
private int size; // <-- initialized to 0
// ... snip
}

You need to implement the default constructor to initialize this object state to the defaults you want (in the stack() method). When you call push, the isFull method will return false (as the default integer value of 0 != -1).

Instead of implementing a default constructor, you could just call stack() before using it, but there's no reason to let your object be constructed in a booby-trapped state!

Additionally, your isFull method should be checking sp against the size variable, right now it is behaving as an isEmpty check :-)

share|improve this answer
 
I thought that is what the 'public void stack(T t) method was doing? –  Christopher Day Mar 14 at 0:39
1  
@ChristopherDay - is does, but you aren't calling that method in the main method above! Also, see my comment about booby trapped objects! You should always make sure (if at all possible) that your object is in a sane state and ready to use after construction. –  Ron Dahlgren Mar 14 at 0:41
 
See PM 77-1 answer below, for the remaining additional bug related to your isFull acting semantically like an isEmpty call –  Ron Dahlgren Mar 14 at 0:44
 
Having also read the additional comment, I now understand what you meant, lol. Thank you for your time and help! Sometimes I wish we could vote for an assist. –  Christopher Day Mar 14 at 0:46
add comment

You're not using any selfdefined constructor. You're using the default one which causes your sp variable to be '0' instead of '-1'. This results in an sp value of 3 after your pushing, but sp[3] has no data in it which results in a NPE when you're trying to pop it.

Change your stack method to

public ArrayStack(T t){
       sp = -1;
       size = 24; //sets the default size of the stack
       head = (T[]) new Object [size];
}

to make it a selfdefined constructor.

share|improve this answer
 
Thank you very much; I had to make an additional change your suggestion worked. –  Christopher Day Mar 14 at 0:44
add comment

After you push "Hello" (1st object) sp becomes 0 and head[0] is assigned. From this moment all further "pushes" will produce nothing since your IsFull is still testing (sp == -1).

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.