View Full Version : [Java]Array Exception
Killer Application
13-02-2008, 17:07
Sto progettando un piccolo software per l'università e mi è venuto fuori questo errore
ArrayIndexOutOfBoundsException:
at java.lang.reflect.Array.get(Native Method)
ho letto su internet che appare se si vuole mettere un valore all'interno di una posizione di un array che non esiste;
ad esempio se voglio mettere qualcosa nella posizione 10 di un array che arriva al massimo a 8.
Qualcuno mi puo spiegare meglio questo errore?
(perche non credo di aver fatto un errore tanto stupido)
Grazie:D
banryu79
13-02-2008, 17:11
Documentazione ufficiale SUN :
-> javadoc for class ArrayIndexOutOfBoundsException (http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ArrayIndexOutOfBoundsException.html)
public class ArrayIndexOutOfBoundsException
extends IndexOutOfBoundsException
Thrown to indicate that an array has been accessed with an illegal index. The index is either negative or greater than or equal to the size of the array.
Tradotto: E' un'eccezione che viene lanciata per indicare un tentativo di accesso all'array stesso tramite un indice illegale.
L'indice è illegale perchè è un numero negativo oppure perchè è un numero uguale o maggiore al "size" (alla dimensione) dell'array.
Ciao :)
se poi nn riesci a trovare l'errore posta il codice e vediamo... ciao :D
JuliusIT
14-02-2008, 07:28
A volte capita perchè non si considera che l'indice di array e collection inizia da 0 e non da 1.
Killer Application
14-02-2008, 10:39
ho perso la testa mezza serata e non ho tolto un ragno dal buco.
ho ricontrollato tutti i for i if del caso ma nada....
Ho controllato anche l'errore dell'inizio dell'array come suggerito (ovvero che parte da 0) ma niente.
a questo punto non so che fare!
se qualcuno mi puo dare una mano in pvt ne sarei grato, perche non posso postare il codice in pubblico.
Ah non vi spaventate sono giusto una 40 di linee di codice per ora quindi niente di che:D
FedeX_65246X
14-02-2008, 11:07
Se e' un'applicazione multithread probabilmente due o piu'
thread stanno accedendo in modo concorrente alla stessa struttura dati senza un'opportuna sincronizzazione.
Per esempio un thread rimuove un elemento mentre un altro cerca di recuperare lo stesso elemento (credendo sia ancora nella struttura).
Ho controllato anche l'errore dell'inizio dell'array come suggerito (ovvero che parte da 0) ma niente.
potrebbe anche essere alla fine, fino a dove arrivi?
Killer Application
14-02-2008, 11:15
Se e' un'applicazione multithread probabilmente due o piu'
thread stanno accedendo in modo concorrente alla stessa struttura dati senza un'opportuna sincronizzazione.
Per esempio un thread rimuove un elemento mentre un altro cerca di recuperare lo stesso elemento (credendo sia ancora nella struttura).
ecco questa cosa non la sapevo e credo che sia proprio questo il guaio, infatti nel mio programma ci sono un paio di funzioni che agiscono su una stessa matrice.
però non so come venirne a capo, cioè ho capito l'errore ma non so come risolverlo:D :muro:
Ma in questo caso perche' lancia ArrayIndexOutOfBoundsException,
che non c'entra una?
Killer Application
14-02-2008, 11:17
potrebbe anche essere alla fine, fino a dove arrivi?
questa non l'ho capita:D
aspetta credo di aver capito cio che dici, allora mettiamo che creo una matrice[10]
l'ultimo elemento di essa sarà matrice[9].
era questo quello che intendevi?
Esatto, quella ecc. viene lanciata se usi un indice <0 o >=dimensione
FedeX_65246X
14-02-2008, 11:30
Ma in questo caso perche' lancia ArrayIndexOutOfBoundsException,
che non c'entra una?
Thread1: controllo dimensione array, t1_size = M
Thread2: rimuovo elemento n, t2_size = M - 1
Thread1: recupero ultimo elemento,
get(t1_size-1) = get (M-1)
OutOfBoundEx
Killer Application
14-02-2008, 11:33
Esatto, quella ecc. viene lanciata se usi un indice <0 o >=dimensione
ma il fatto è che ho controllato, ma adesso mi sorge un dubbio.
supponiamo sta stringa
matrice è una string
matrice[9]="14";
int idi = Integer.parseInt(matrice[9]);
for(int i = 0; i<10;i++){
if (matrice_appoggio[i][idi]!="//"){
matrice_appoggio[i][idi]=matrice[3]
};
};
il comando integer.parseInt estrae dalla matrice[9] il numero e lo mette come int in "idi" giusto?
Killer Application
14-02-2008, 11:35
Thread1: controllo dimensione array, t1_size = M
Thread2: rimuovo elemento n, t2_size = M - 1
Thread1: recupero ultimo elemento,
get(t1_size-1) = get (M-1)
OutOfBoundEx
posso mandarti un pm con il codice?:help:
perche credo sia questo l'errore ma non riesco a trovarlo
banryu79
14-02-2008, 13:03
Potresti sempre sostituire gli array di primitive (o di String) che usi nel codice con dei Vector (di primitive o di String), dato che la classe Vector è syncronized...
Inoltre se usi un Iterator per scandire il Vector, in caso qualche altro thread tenti di accedere al Vector per modificarlo parte una bella ConcurrentModificationException e così sai che il problema è quello.
dato che la classe Vector è syncronized...Sì ma questo non elimina tutti i problemi!! Cioè il fatto che una collezione sia synchronized vuol solo dire che la mutua esclusione è sulla singola invocazione di 1 metodo.
Se su una collezione si devono fare operazioni composte, del tipo check-then-act o read-modify-write, allora anche se la collezione in sé è synchronized, la sequenza va fatta in modo atomico e quindi è necessario effettuare il client-side locking, se la collezione lo permette.
Killer Application
14-02-2008, 13:33
rignrazio per i consigli ma sono ancora a uno step base si java.
quindi ancora niente vector, e il prof consiglia di usare gli strumenti utilizzati in classe.
banryu79
14-02-2008, 14:13
Se su una collezione si devono fare operazioni composte, del tipo check-then-act o read-modify-write, allora anche se la collezione in sé è synchronized, la sequenza va fatta in modo atomico e quindi è necessario effettuare il client-side locking, se la collezione lo permette.
Daccordo, ma usando per esempio un'ArrayList al posto degli array e manipolando le istanze della collection solo attraverso l'Iterator può comunque verificare se viene lanciata una ConcurentModificationException...
Questo a patto che le manipolazioni desiderate (scusate l'espressione un poco ambigua :D ) possano essere interamente implementate usando solo l'Iterator, giusto?
Non ho capito tutte le implicazioni della tua osservazione circa il fatto che se anche la collection fosse syncronized sarebbe comunque neccessario fornire altre garanzie: basterebbe per esempio sincronizzare l'intero metodo che opera sulla collection stessa, per esempio? (dove posso documentarmi nello specifico?)
Daccordo, ma usando per esempio un'ArrayList al posto degli array e manipolando le istanze della collection solo attraverso l'Iterator può comunque verificare se viene lanciata una ConcurentModificationException...Qui ci sarebbero da dire altre cose, ad esempio che il comportamento "fail-fast" degli iteratori nelle principali collezioni di base non è garantito al 100%. Cioè per come è stato implementato, se un thread concorrente modifica la collezione, potrebbe anche capitare che l'iteratore non se ne accorga.
Quindi il comportamento fail-fast è da usare solo per rilevare dei bug, cioè appunto se sbuca fuori un ConcurrentModificationException, allora è un bug e basta.
Non ho capito tutte le implicazioni della tua osservazione circa il fatto che se anche la collection fosse syncronized sarebbe comunque neccessario fornire altre garanzie: basterebbe per esempio sincronizzare l'intero metodo che opera sulla collection stessa, per esempio? (dove posso documentarmi nello specifico?)Per fare un esempio, se voglio eliminare l'ultimo elemento di un Vector (e non c'è infatti un singolo metodo synchronized apposito per questo), dovrei fare:
Vector v = .....
synchronized (v) {
int size = v.size ();
if (size > 0)
v.remove (size-1);
}
Tutta la sequenza deve essere atomica, per questo va fatta tenendo il lock per tutta la sequenza. Che poi lo faccia come blocco synchronized o come metodo synchronized, è indifferente. Ma va fatto, nonostante i singoli metodi di Vector siano synchronized!
^TiGeRShArK^
14-02-2008, 15:13
e comunque è consigliato utilizzare al posto delle vecchie classi che implementano synchronized (come Vector) le nuove classi (come ArrayList) wrappandole con Collections.synchronizedList(List<T> list) :p
banryu79
14-02-2008, 15:15
Per fare un esempio, se voglio eliminare l'ultimo elemento di un Vector (e non c'è infatti un singolo metodo synchronized apposito per questo), dovrei fare:
Vector v = .....
synchronized (v) {
int size = v.size ();
if (size > 0)
v.remove (size-1);
}
Tutta la sequenza deve essere atomica, per questo va fatta tenendo il lock per tutta la sequenza. Che poi lo faccia come blocco synchronized o come metodo synchronized, è indifferente. Ma va fatto, nonostante i singoli metodi di Vector siano synchronized!
Capito, nel frattempo mi sono spulcito qualcosa anche online e il tuo qui presente esempio è stato la ciliegina sulla torta.
A proposito, grazie infinite per la disponibilità dimostrata e la chiarezza :)
Thread1: controllo dimensione array, t1_size = M
Thread2: rimuovo elemento n, t2_size = M - 1
Thread1: recupero ultimo elemento,
get(t1_size-1) = get (M-1)
OutOfBoundEx
Rimuovo elemento? Da un array?
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.