Newsgroup: it.comp.java
Titolo: errore accedendo ad array appena inizializzato

Hoil seguente codice:
import java.util.*;
public class Graph {
  public Graph(int num_node) {
    num_max_node=num_node;
    graph_nodes = new GNode [num_max_node];
    for (int i=0;i<num_max_node;i++){
*      graph_nodes[i].info=null;
*      graph_nodes[i].succnodes=new int[num_max_node];
      for (int j=0;j< num_max_node;j++){
        graph_nodes[i].succnodes[j]=0;
      }
    }
  }
  // Metodi pubblici della classe graph
  class GNode{
    public Object info;
    public int [] succnodes; // peso associato agli archi; 0 indica non
presente
  }
  private GNode [] graph_nodes;
  private int num_max_node ;
  private int tipo;
}
Al momento in cui dichiaro un aoggetto di tipo Graph e ne vado a fare
l'inizializzazione, quando l'esecuzione arriva alle due righe contrassengate
con * mi viene restituita un'eccezione java.lang.NullPointerException.
Qualcunopuň spiegarmi perchč? Non riesco a capire dove sbaglio

> Qualcunopuň spiegarmi perchč? Non riesco a capire dove sbaglio
Perchč il contenuto della "casella" dell'array č nullo.
    for (int i=0;i<num_max_node;i++){
***  graph_nodes[i] = new GNode(whatever parameters);
        graph_nodes[i].info=null;
        graph_nodes[i].succnodes=new int[num_max_node];
    regards,
        Kazuma
--
I've got nothing against God. It's his fan club I can't stand.
Alex "Kazuma" Garbagnati, 
http://www.kazuma.net
EJB & Tomcat jGuru FAQ Manager, 
http://www.jGuru.com
Tutor "Progetto Scuole", 
http://www.JIA.it
Java Italian Association - SUN - MIUR

         graph_nodes[i].succnodes=new int[num_max_node];
Cosa significa la riga con i tre asterischi?


Ah vediamo se ho capito bene.
Inpratica dopo aver creato un array di GNode, devo specificare direttamente
che ogni nodo appartiene alla classe Gnode.
Ma come mai questo non viene fatto direttamente nell'inizializzazione
dell'array?


è per indicare quella da aggiungere
	regards,
		Kazuma
---


dell'array?
No.
Java garantisce l'inizializzazione degli elementi di un array a quelli
che sono i valori di default stabiliti dalle specifiche del
linguaggio.
Nel caso di un oggetto, questo valore è null, quindi il tuo oggetto è
nullo.
	regards,
		Kazuma
---


         graph_nodes[i].succnodes[j]=0;
proprio perché gli array alla creazione vengono inizializzati con i valori
di default non c'é bisogno di quel ciclo per mettere a zero
graph_nodes[i].succnodes essendo 0 il valore di default.
Per altro puo' esserti utile sapere che c'é il metodo Arrays.fill() per fare
questi sporchi lavori di riempimento :)
(Immagino che fill non usi le assegnazioni ma delle istruzioni orientate al
bit (& logico con 0?) per rendere la cosa piu' rapida, tipo, se non sbaglio
bzero() o memset() del C. Ma se qualcuno ne sa qualcosa gradirei saperlo
anch'io :))
Ciao
Matteo

 graph_nodes[i].succnodes essendo 0 il valore di default.
E' necessario, invece, perchè il vaore di default di un oggetto, per
specifiche Java, è null. Quindi il contenuto di tutti gli elementi
dell'array è null, e da qui il sano "NullPointerException"
    Regards,
        Kazuma


 dell'array è null, e da qui il sano "NullPointerException"
Guarda che Matteo parla della inizializzazione:
    for (int j=0;j< num_max_node;j++){
       graph_nodes[i].succnodes[j]=0;
    }
e, quindi, ha ragione Matteo dicendo che questa inizializzazione a 0
non serve proprio a niente!
- Dario

 non serve proprio a niente!
In effetti č vero..., ho letto male il messaggio.
Piccolo appunto: non essendoci il codice sorgente della classe Graph_Nodes,
non esiste alcuna certezza che l'array succnodes presente in Graph_Nodes non
sia, all'interno del costruttore) inizializzato in modo differente
(magari -1) o che altre variabili siano inizializzate non col vaore di
feualt di Java...
Quindi in parte... hehehehe
Comunque si, mea culpa...


 vaore di feualt di Java...
<warning: istinto dell'ingegnere rompipalle attivo>
public Graph(int num_node) {
    num_max_node=num_node;
    graph_nodes = new GNode [num_max_node];
    for (int i=0;i<num_max_node;i++){
      graph_nodes[i] = new GNode(parameters);
      graph_nodes[i].info=null;
      graph_nodes[i].succnodes=new int[num_max_node];
/* nell'istruzione qui sopra a graph_nodes[i].succnodes (un riferimento di
tipo int[]) viene assegnato un nuovo array di int, cioé un array bello
pieno di zeri, a prescindere da quello che l'inizializzazione nella classe
GNode gli aveva assegnato.
Per questa ragione il ciclo qui sotto è perfettamente inutile.
                                                                */
      for (int j=0;j< num_max_node;j++){
        graph_nodes[i].succnodes[j]=0;
      }
    }
  }
<-- istinto dell'ingegnere rompipalle disattivato -->
A questo punto vorrei aggiungere che il codice dovrebbe diventare qualcosa
del genere:
public Graph(int num_node) {
    num_max_node=num_node;
    graph_nodes = new GNode [num_max_node];
    for (int i=0;i<num_max_node;i++)
      graph_nodes[i] = new GNode(info,num_max_node);
}
Che ne dici?
Ciao
Matteo

     graph_nodes = new GNode [num_max_node];
*     Arrays.fill(graph_nodes, new GNode(info,num_max_node));
