problem to get the right value from my hashmap

0 votes
asked Oct 20 by HMSVictory (120 points)
Here is my main problem. I am simulating a process with a register, memory and a constant value

when calling the following code from app.class

new Set(new Reg("A"),new  Reg("B")),
                      new Set(new Reg("A"),new  Mem(20)),
                      new Set(new Reg("A"),new  Val(2000)),
                      new Set(new Mem(10),new  Reg("B")),*/
                      new Set(new Mem(10),new  Mem(20)),
                      new Set(new Mem(10),new  Val(2000))

it's supposed to return the values from method getReg, getMemoryElmt from Machine class but unfortunately I get this kind of error message :

0. Set ([email protected], [email protected])
1. Set ([email protected], [email protected])

0
0
0
0

Set ([email protected], [email protected])
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 20 out of bounds for length 4
    at Tp3.Machine.getMemoryElmt(Machine.java:70)
    at Tp3.Mem.readValue(Mem.java:17)
    at Tp3.Set.execute(Set.java:22)
    at Tp3.Machine.step(Machine.java:42)
    at Tp3.App.main(App.java:20)

Now I don't know if the problem is the problem is from the methods of machine.java or the methods readValue/setValue from Reg/Val/Mem class

App class containing Main

public class App {

    public static void main(String[] args) {
        Machine m = new Machine(4);
        m.setProgram(
                      new Set(new Reg("A"),new  Reg("B")),
                      new Set(new Reg("A"),new  Mem(20)),
                      new Set(new Reg("A"),new  Val(2000)),
                      new Set(new Mem(10),new  Reg("B")),
                      new Set(new Mem(10),new  Mem(20)),
                      new Set(new Mem(10),new  Val(2000))
                    );
        m.printProgram();
        System.out.println();
        do {
            m.printMemory();
            System.out.println();
        } while (m.step());
        m.printMemory();
    }
}

Execute method from Set launching execution

public class Set extends Instruction {

    private  Ecriture e;
    private Lecture l;

    Set(Ecriture e,Lecture l) {
        this.e = e;
        this.l = l;
    }
    

    @Override
    public String toString() {
        return "Set (" + e + ", " + l + ")";
    }
    
    @Override
    boolean execute(Machine m) {
        System.out.println(this);
        e.setValue(m, l.readValue(m));
        return true;
    }

}

Machine class

public class Machine {

    private List<Instruction> instructions;
    private int[] memory;
    private int current;
    private HashMap<String,Integer>reg;

    public Machine(int memorySize) {
        memory = new int[memorySize];
        reg = new HashMap<String,Integer>();
        instructions = new ArrayList<>();
        reset();
    }

    public void setProgram(Instruction... args) {
        for (int i = 0; i < args.length; i++)
            instructions.add(args[i]);
    }

    public void printProgram() {
        System.out.println(current + ". " + instructions.get(current));
        while (nextInstruction()) {
            System.out.println(current + ". " + instructions.get(current));
        }
        reset();
    }

    public void printMemory() {
        for (Integer i : memory) {
            System.out.println(i);
        }
    }

    public boolean step() {
        return instructions.get(current).execute(this);
    }

    boolean nextInstruction() {
        if (current < instructions.size() - 1) {
            current++;
            return true;
        } else
            return false;
    }

    boolean setCurrent(int index) {
        if (index < instructions.size()) {
            current = index;
            return true;
        }
        return false;
    }
    
     int getCurrent() {
        return current;
    }

     int getMemorySize() {
        return memory.length;
    }

     int getMemoryElmt(int index) {
        return memory[index];
    }

    boolean setMemory(int index, int value) {
        if (index < memory.length) {
            memory[index] = value;
            return true;
        }
        return false;
    }
    
    int getReg(String index) {
        return reg.get(index);
    }
    
    boolean setReg(String value, int index) {
        if(value!=null) {
            reg.put(value,index);
            return true;
        }
        return false;
    }

    void reset() {
        current = 0;
    }
}

Registre class

public class Reg implements Lecture,Ecriture{
    private String registre;
    
    public Reg(String r){
        this.registre = r;
    }
    
    public String getReg() {
        return registre;
    }

    @Override
    public void setValue(Machine m, int v) {
        m.setReg(this.getReg(), v);
    }

    @Override
    public int readValue(Machine m) {
        return m.getReg(this.getReg());
    }

    
}

Mem class

public class Mem implements Lecture,Ecriture{
    private int memory;
    
    public Mem(int mem) {
        this.memory = mem;
    }
    
    public int getMem() {
        return memory;
    }

    
    @Override
    public int readValue(Machine m) {
        return m.getMemoryElmt(this.getMem());
    }
    
    @Override
    public void setValue(Machine m, int v) {
        m.setMemory(this.getMem(), v);
    }
    
}

Val class

public class Val implements Lecture{
    private int value;
    
    public Val(int v) {
        this.value = v;
    }
    
    public int getVal() {
        return value;
    }

    @Override
    public int readValue(Machine m) {
        // TODO Auto-generated method stub
        return getVal();
    }
}

1 Answer

+1 vote
answered Oct 22 by Peter Minarik (12,220 points)

How To Read The Calls Stack

This is the error message followed by the call stack of the error:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 20 out of bounds for length 4
    at Tp3.Machine.getMemoryElmt(Machine.java:70)
    at Tp3.Mem.readValue(Mem.java:17)
    at Tp3.Set.execute(Set.java:22)
    at Tp3.Machine.step(Machine.java:42)
    at Tp3.App.main(App.java:20)

So it says, the exception is that you have an array that is 4 element long, but you're trying to access the 20th element. No such element exists, hence the exception.

Where is this? Well, you start to read the call stack from top to down:

The problem happens in Tp3.Machine.getMemoryElmt(Machine.java:70). This is the location of your exception. The other lines below the call stack explains how you got to the call that ended up causing the problem.

This does not mean that Machine.java:70 is necessarily the faulty line of code, but it's the one that's raises the exception. E.g. if that line of code is trying to access an arbitrary index in an array, it's not the root cause of the fault, but the call that eventually passes the index down here.

So, look at your code, find out if your array should be really 4 elements long. Or maybe you shouldn't try to access the 20th element.

Good luck!

Welcome to OnlineGDB Q&A, where you can ask questions related to programming and OnlineGDB IDE and and receive answers from other members of the community.
...