IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

avec Java Discussion :

Conflit de mémoire entre plusieurs variables


Sujet :

avec Java

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Septembre 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Septembre 2017
    Messages : 6
    Points : 6
    Points
    6
    Par défaut Conflit de mémoire entre plusieurs variables
    Bonjour,

    J'ai un problème qui vient vraisemblablement d'un conflit de mémoire entre plusieurs variables, je butte sur ce problème depuis plus d'une semaine, j'ai demandé de l'aide a plusieurs amis meilleurs que moi en java, j'ai fait beaucoup de recherche sur google mais rien a faire...
    Voici le bout de code qui ne marche pas:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
     if(listeSituations.size() > 0)
    		{
    			System.out.print("1:  " + ((MorpionSituation) listeSituations.get(0)).getSituation() + "\n1:  ");
    			displayLine(((MorpionSituation) listeSituations.get(0)).getSituation());
    		}
     
    		int[] temp = new int[10];
     
    		if(listeSituations.size() > 0)
    			temp = ((MorpionSituation) listeSituations.get(0)).getSituation();
     
    		displayLine(temp);
     
                    plateau[position] = joueur;
     
                   displayLine(temp);
     
                   if(listeSituations.size() > 0)
            	        ((MorpionSituation) listeSituations.get(0)).setSituation(temp);
     
                    if(listeSituations.size() > 0)
    		{
    			System.out.print("2:  " + ((MorpionSituation) listeSituations.get(0)).getSituation() + "\n2:  ");
    			displayLine(((MorpionSituation) listeSituations.get(0)).getSituation());
    		}
    La fonction displayLine sert a afficher un tableau:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public static void displayLine(int[] pla)
    	{
    		for(int i : pla)
    			System.out.print(i);
     
    		System.out.print("\n");
    	}
    plateau est un int[] static déclaré en dehors de la main:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
           private static final int[] plateau = {0,0,0, 0,0,0, 0,0,0};
    listeSituations est une ArrayList (déclarée en dehors de la main) composée d'un seul objet MorpionSituation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    	private static ArrayList<MorpionSituation> listeSituations = new ArrayList<MorpionSituation>();
    //Création de l'objet MorpionSituation:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
                            int[] temp = new int[9];
    			temp = plateau;
    			MorpionSituation sit = new MorpionSituation(temp);
    			listeSituations.add(sit);
    L'objet MorpionSituation contient une variable situation accessible par la fonction getSituation:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    	public MorpionSituation(int[] plat) {
    		this.temp = plat;
    		this.situation = this.temp;
    	}
     
    	public int[] getSituation() {
    		return this.situation;
    	}
     
    	public void setSituation(int[] newSituation) {
    		situation = newSituation;
    	}
    Et tout ce beau monde affiche ça :

    1: [I@7ba4f24f
    1: 000010000
    000010000
    000210000
    2: [I@7ba4f24f
    2: 000210000


    Explication:
    Avant de lancer le bout de code du début, plateau vaut 000010000, les 3 premieres lignes sont normales, ensuite on modifie plateau sans toucher a situation, puis on affiche situation et on voit qu'elle a changé -________-'


    Please help !

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    Le souci vient de l'affectation.

    Quand tu écris
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int[] tableau1 = new int[9]
    int[] tableau2 = tableau1;
    Tu ne fais pas la copie des éléments du tableau1 dans le tableau2, tu affectes la valeur contenue dans la variable tableau1 à la variable2. Ici, la valeur contenue dans tableau1 est une reférence vers un tableau (une sorte d'adresse mémoire, ou une sorte d'identifiant de zone mémoire, mais interne à la JVM). Donc après tableau2=tableau1; , tableau2 contient la référence à la même zone de mémoire dans laquelle se trouve tableau1, c'est donc le même tableau référencé par 2 variables. Donc si tu écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    tableau2[2]=1;
    System.out.println(tableau1[2]);
    ça t'affiche 1, parce que c'est la même chose, juste représenté par 2 variables différentes.


    C'est exactement la même chose si tu écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int[] tab1 = new int[9];
    List<int[]> list = new ArrayList<>();
    for(int i=0; i<10; i++) {
    	int[] tab2 = tab1;
    	list.add(tab2);
    }
    tab1[1] = 1;
    for(int[] tab : list) {
    	for(int i : tab) System.out.print(i);
    	System.out.println();
    }
    ça affiche :
    010000000
    010000000
    010000000
    010000000
    010000000
    010000000
    010000000
    010000000
    010000000
    010000000
    Dans la liste, tu as simplement 10 fois le même tableau.

    1. Pour copier un tableau dans un autre :
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      public static void copyTo(int[] tab1, int[] tab2) {
      		System.arraycopy(tab1, 0, tab2, 0, Math.min(tab1.length, tab2.length));
      	}
      	public static int[] createCopy(int[] tab1) {
      		int[] tab2 = new int[tab1.length];
      		System.arraycopy(tab1, 0, tab2, 0, tab1.length);
      		return tab2;
      	}
       
      	public static int[] createCopy2(int[] tab1) {
      		return Arrays.copyOf(tab1, tab1.length);
      	}
    [*]pour remplir un tableau, par exemple de 0 :
    A noter que à la création, un tableau de int contient des 0.
    est équivalent à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int[] tab={0,0,0,0,0,0,0,0,0};
    est équivalent à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    int[] tab=new int[]{0,0,0,0,0,0,0,0,0};
    La première écriture restant la plus courte et la plus simple.[/LIST]

    Au passage, quand tu écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int[] temp = new int[9];
    			temp = plateau;
    Tu crées un tableau de 9 cases, qui ensuite est perdu, puisque temp contient la référence contenue dans plateau. Tu crées donc un tableau pour rien. Ce n'est pas très grave dans ton cas, il va juste occuper de la mémoire jusqu'à ce que le GarbageCollector décide de le virer parce qu'il a besoin de place pour un autre objet. Mais dans une application réelle, où des centaines de milliers d'objets peuvent être créé, en créer pour rien peut être couteux : lorsqu'il y aura besoin de mémoire pour des objets, le Garbage Collector va prendre beaucoup de temps pour nettoyer la mémoire de tout un tas d'objets qui n'auront jamais servi à rien, puisque jamais utilisés.

    Si ce n'est une copie, int[] temp = plateau; suffit, et pour une copie int[] temp = Arrays.copy(plateau,plateau.length);.

    Dernière remarque : à moins d'avoir besoin d'un "affichage" particulier, System.out.println(Arrays.toString(tab)); est un moyen simple d'afficher le tableau tab en console.
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Lycéen
    Inscrit en
    Septembre 2017
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Lycéen

    Informations forums :
    Inscription : Septembre 2017
    Messages : 6
    Points : 6
    Points
    6
    Par défaut
    Ok merci beaucoup pour ta réponse super complète

    Juste pour les multiples petits tableaux temp je sais que c'est inutile, c'est simplement que j'ai oublié de les enlever (je les ai mis parce que j'étais désespéré, j’essayais de trouver un moyen de résoudre le problème x) )

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 25/04/2017, 09h53
  2. Corrélations entre plusieurs variables
    Par Dideal18 dans le forum MATLAB
    Réponses: 1
    Dernier message: 24/09/2013, 09h01
  3. Partage de variables entre plusieurs pages
    Par bud_gw dans le forum Général JavaScript
    Réponses: 10
    Dernier message: 27/12/2005, 15h42
  4. Gestion de la mémoire entre plusieurs DLL
    Par Laurent Gomila dans le forum C++
    Réponses: 7
    Dernier message: 27/07/2004, 15h28
  5. [Technique] Conflits entre plusieurs requêtes
    Par Neowile dans le forum Décisions SGBD
    Réponses: 3
    Dernier message: 24/03/2003, 09h37

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo