Problem 19 What wrong with my code? (with code)(java)(javalangNullPointerException)

Back to Problem Solutions forum

Pavel_Emelyanov     2019-03-06 11:42:09
User avatar
import java.util.Scanner;

public class Main{
public static void main (String[] args){

    Scanner keyboard = new Scanner(System.in);
    // numb of strings
    int numOfTest = Integer.parseInt(keyboard.nextLine());

    // create to spec arr, for "open char" and "closer char"
    char specArrOp[] = { '<', '(', '[', '{' };
    char specArrCl[] = { '>', '}', ']', '}' };

    // condition of check.
    boolean cond;


    // for each string
    for(int t = 0; t < numOfTest; t++) {
        int stopper = 1;
    // read string and create stack
        String str = keyboard.nextLine();
        Stack stack = new Stack(str.length());
    //transform string into char[]
        char strArr[] = str.toCharArray();
    //for each char
        stackloop:
        for (int i = 0; i < str.length() - 1; i++) {
            // check: Is char special simbol
            for (int j = 0; j < specArrOp.length - 1; j++) {
                //if it is openSymb push it into stack
                if (strArr[i] == specArrOp[j]) {
                    stack.push(strArr[i]);
                    break;
                }
                //if it is closeSymb check last openSymb in stack
                if (strArr[i] == specArrCl[j]) {
                    //is it his openSymb?
                    cond = stack.pop(specArrCl[j]);
                    //if it isnt, so result is 0, end with that string;
                    if (!cond) {
                        stopper = 0;
                        break stackloop;
                    }
                    break;
                }
            }
        }
        // output 0 or 1, when string ended.
        System.out.print(stopper);
    }
}
}


class Stack{
char Arr[];
int tos; // pointer

//Constructor
Stack (int size){
    char Arr[] = new char[size*2];
    tos = -1;
}
// to add char into stack
void push (char ch){
    Arr[++tos] = ch;
}
// to get char from stack
boolean pop (char ch){
    // if stack is empty it is impossible to take anything from it ;)
    if(tos == -1){
        System.out.print("Stack is empty");
        return false;
    }

    // for each special symbol define his openSymb pair, if last char in stack is his openSymb return true and pointer - 1;
    if((ch == '>' && Arr[tos]=='<') || (ch == ')' && Arr[tos]=='(') ||
       (ch == '[' && Arr[tos]==']') || (ch == '}' && Arr[tos]=='{') ){
        Arr[tos] = '0';
        tos--;
        return true;
    }
    // if it is not his openSymb, return false
    else
        return false;
}
}

So this programm doesnt work: Exception in thread "main" java.lang.NullPointerException at Stack.push(Main.java:67) at Main.main(Main.java:33)

I didnt understand why. Look like it is something wrong method push. // to add char into stack void push (char ch){ Arr[++tos] = ch; } where tos is pointer. and tos = -1; so first ch should be into Arr[0], isnt it? or it maybe smth wrong with char strArr[] = str.toCharArray(); because it is first time when i called strArr[i];

Thanks for attentionю

P.S. Sorry, for bad english. And i didnt know how to decribe my prob without pasting code.

Rodion (admin)     2019-03-06 12:54:13
User avatar

Hi there!

Is it ok if I just tell you how to debug this problem - and you try to find out yourself?

See, it complains about NPE in line 33. This line contains

stack.push(strArr[i]);

What can be null here??? Either stack or strArr, probably. Let's try to add a debugging printout in a line before:

if (stack == null || strArr == null) System.out.printf("Null here! i=%s, stack=%s, strArr=%s%n", i, stack, strArr);

So when code execution comes to this point and there is some null which may cause NPE, we shall see output with "Null here" and exact variable values before it crashes. Then we only need find out why some of variables is null.

Hope this helps. If not, feel free to write for further hints!

And i didnt know how to decribe my prob without pasting code.

No worry about it, but if you save your code (when you click "submit" it is saved) we all can see it on your page anyway :)

Pavel_Emelyanov     2019-03-06 16:48:42
User avatar
if (strArr[i] == specArrOp[j]) {

                    System.out.print("Null here! "+  i + " " + stack + " " + strArr[i] + "\n");
                    // Null here! 0 Stack@18be83e4 (
                    if (stack == null || strArr == null)   // stack isnt null, strArr isnt null.
                        System.out.print("Null here! "+ i + " " + strArr[i]);

                    stack.push(strArr[i]);
                    break;
}

Thanks for your hints!

I tryed to output some info about i, stack and strArr[i] if(stack == null || strArr == null) always true, so i doesnt help And System.out.print("Null here! " + i + " " + stack + " " + strArr[i]); i = 0; stack = Stack@18be83e4; so he isnt emplty, because i initialized it (23 line) or it is? Stack stack = new Stack(str.length()); Constructor: Stack (int size){ char Arr[] = new char[size]; tos = -1; }

Look like problem in this part, but i cant understand why? Method in (class Stack): void push (char ch){ tos++; Arr[tos] = ch;
} I cant understand why Arr[0] = ch; had NullPointerException I created Stack for string which included Arr[string.length] and tos = -1; So that method received ch. ch isnt null. ch = < { [ (; next tos++. so tos = 0 first time; Arr[0] = ch;

So stack.Arr[0] is null (35 line)but should I initialize each element of the array when I create an instance of the class stack?

Thanks for you help)

Rodion (admin)     2019-03-06 17:06:50
User avatar

Oh my, I got it. Sorry for misleading you first.

It is NPE from push method. I didn't noticed first you have your implementation of Stack...

See:

class Stack{
    char Arr[];  // this is "instance" variable, field of the object, "null" initially

    Stack (int size){
        char Arr[] = new char[size*2]; // this is local variable in constructor
        // it is not related to Arr above
    }
}

you wanted something like this

    Stack (int size){
        Arr[] = new char[size*2]; // now you don't declare variable, just assign to field
    }

If you don't mind, I dare also suggest few hints:

  • don't write these comments like //for blah-blah or //Constructor - you usually see this from code without comments, but they make code bloat and unreadable without syntax highlight :) comments should be used carefully and thoughtfully...
  • don't dive too deep into object/classes manipulation while you are learning basics - everything will come in time but Java is a bit complicated for newcomer and we don't want you to get frustrated :)
  • don't write your own classes (like Stack) for things which already exist in library (ArrayList or Stack in java.util)
  • if you use Eclipse or Idea or NetBeans - there should be "step-by-step" debugger helpful in such cases, google for some instructions or youtube video - it allows to check all variables easily...

Hopefully this helps!

Please login and solve 5 problems to be able to post at forum