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

C++ Discussion :

delete provoque un plantage


Sujet :

C++

  1. #1
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut delete provoque un plantage
    Bonjour,

    J'ai une méthode assez courte dans laquelle j'alloue dynamiquement de la mémoire pour le pointeur nommé dataArray :

    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
     
    int geometry::updateDynamicData(int current_key)
    {
    	MMatrix *matricesArray = new MMatrix[mMotionKeys];
    	AtArray *dataArray;
    	dataArray = new AtArray;
    	dataArray = nodeGetArray(handle, "matrix");
    	if (dataArray->data != NULL)
    		matricesArray = (MMatrix*)dataArray->data;
     
    	int offset = current_key-1;
     
    	AtMatrix tmp;
    	MMatrix matrix(mDagPath.inclusiveMatrix());
    	matrix.get(tmp);
    	matricesArray[offset] = tmp;
     
    	setMatrixArray("matrix", &matricesArray, 1, mMotionKeys, false);
     
    	delete dataArray;
    	delete [] matricesArray;
    }
    Quand je laisse le delete en fin de bloc, ça me fait planter mon prgramme.
    Si je l'enlève, c'est OK, même si je suppose ça provoque quelques fuites de mémoire...

  2. #2
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Par défaut
    Ton appel à new pour allouer de la mémoire ne sert strictement à rien, puisqu'à la ligne d'après tu réaffectes dataArray pour le faire pointer ailleurs.

    J'imagine que si le delete plante c'est que nodeGetArray ne renvoie pas un objet qui a été alloué correctement avec new. On peut voir le code de cette fonction ?

  3. #3
    screetch
    Invité(e)
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    	AtArray *dataArray;
    	dataArray = new AtArray;
    	dataArray = nodeGetArray(handle, "matrix");
    je pense que tu n'as pas compris la fonctionnalité de new et delete.

    Ici new sert a allouer un objet AtArray et place l'adresse ou il a ete créé dans la variable dataArray.
    A la ligne du dessous, tu affectes dans la variable contenant l'adresse de ce nouvel objet l'adresse renvoyee par nodeGetArray(handle, "matrix");
    cette fonction te renvoie ladresse d'un objet deja existant.

    ensuite, delete va essayer de liberer l'objet qui est pointé par dataArray, qui n'est pas l'objet créé au debut puisque son adresse a ete remplacee par l'adresse d'un autre objet.

    En gros supprime le new, tu cherches a obtenir l'adresse d'un objet deja existant. Et supprime delete, puisque tu n'as pas alloué toi meme cet objet.

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    J'ai supprimé le new et le delete pour dataArray, et cela fonctionne à merveille.
    Je vous remercie donc pour vos explications.

    En revanche, j'ai le problème équivalent pour matricesArray (dont j'avais oublié la déclaration, rajoutée en première ligne).

    Là, si j'enlève le new, ça ne fonctionne pas.
    Et si je rajoute le delete [], ça ne fonctionne pas non plus.

  5. #5
    screetch
    Invité(e)
    Par défaut
    une possibilite pour laquelle ca ne marche pas sans le new est que tu affectes matricesArray seulement dans certaines conditions et pas dans d'autre.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    {
    	MMatrix *matricesArray;
    	AtArray *dataArray;
    	// non! dataArray = new AtArray;
    	dataArray = nodeGetArray(handle, "matrix");
    	if (dataArray->data != NULL)
    		matricesArray = (MMatrix*)dataArray->data;
    	else
    		matricesArray = 0; // c'est a toi de savoir ce que l'on fait si
    			// il n y a pas de data mais tu ne peux pas laisser
    			// matricesArray non initialise
    	...
    	// non! delete dataArray;
    }

  6. #6
    Membre chevronné
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2006
    Messages
    366
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2006
    Messages : 366
    Par défaut
    Citation Envoyé par oodini Voir le message
    Là, si j'enlève le new, ça ne fonctionne pas.
    Cad ? (quelle erreur est obtenue ?)

  7. #7
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par screetch Voir le message
    une possibilite pour laquelle ca ne marche pas sans le new est que tu affectes matricesArray seulement dans certaines conditions et pas dans d'autre.
    Ben en fait, si le if échoue, je dois créer le tableau, et je devrais donc utiliser un new....

    Ce que j'ai fait : j'ai déporté le new dans le else.

    Ca fonctionne, mais quid de la désallocation de la mémoire ?

    Si je fais un delete[] en fin de bloc, ça couine.

  8. #8
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Citation Envoyé par bolhrak Voir le message
    Cad ? (quelle erreur est obtenue ?)
    Mon programme mouline dans le vide (freeze ?), quand je fais ça.

  9. #9
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Bon, avec le if, j'ai rajouté un else utilisant un booléen dédié appelé initialisation :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    	if (dataArray->data != NULL)
    	{
    		matricesArray = (MMatrix*)dataArray->data;
    	}
    	else
    	{
    		matricesArray = new MMatrix[mMotionKeys];
    		initialisation = true;
    	}
    Ensuite, en fin de bloc, je mets cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	if (initialisation)
    		delete [] matricesArray;
    Ca marche, mais je ne sais pas si c'est ce qu'il a de mieux à faire... :-/

  10. #10
    Membre éclairé Avatar de befalimpertinent
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    561
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Avril 2007
    Messages : 561
    Par défaut
    Citation Envoyé par oodini Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    	if (dataArray->data != NULL)
    	{
    		matricesArray = (MMatrix*)dataArray->data;
    	}
    	else
    	{
    		matricesArray = new MMatrix[mMotionKeys];
    		initialisation = true;
    	}
    Ensuite, en fin de bloc, je mets cela :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	if (initialisation)
    		delete [] matricesArray;
    Ca marche, mais je ne sais pas si c'est ce qu'il a de mieux à faire... :-/
    C'est correct si l'allocation / désalocation de cet objet
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    (MMatrix*)dataArray->data;
    est fait correctement. Montres nous ça dans ton code

  11. #11
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    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
    26
    27
    28
    29
    30
    31
    32
    int Geometry::updateDynamicData(int current_key)
    {
    	MMatrix *matricesArray;
     
    	bool initialisation = false;
     
    	AtArray *dataArray;
    	dataArray = AiNodeGetArray(handle, "matrix");
    	if (dataArray->data != NULL)
    	{
    		matricesArray = (MMatrix*)dataArray->data;
    	}
    	else
    	{
    		matricesArray = new MMatrix[mMotionKeys];
    		initialisation = true;
    	}
     
    	int offset = current_key-1;
     
    	AtMatrix tmp;
    	MMatrix matrix(mDagPath.inclusiveMatrix());
    	matrix.get(tmp);
    	matricesArray[offset] = tmp;
     
    	setMatrixArray("matrix", &matricesArray, 1, mMotionKeys, false);
     
    	if (initialisation)
    		delete [] matricesArray;
     
    	return true;
    }

  12. #12
    screetch
    Invité(e)
    Par défaut
    Quand tu passes par des pointeurs l'important est de savoir QUI obtient la "possession" (l'ownership, la proprieté) de ton pointeur, et qui va le liberer donc.

    Si tu recuperes un pointeur de quelquun, il n'est pas a toi, tu ne dois pas le liberer, sauf si cette personne/objet/machin te TRANSMET la proprieté (c'est en general precisé en gros)

    Dans ton code essaye d'etablir qui a la propriete des objets alloues avec new, c'est a eux de faire la desallocation avec delete.

    A la rigueur si tu as du mal a voir, nomme uen variable MYptr, MYmatrix, et desalloue la a la fin.

    Exemple :

    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
     
    	AtArray *dataArray; // pas a moi
    	MMatrix *matricesArray; // pas a moi a priori
    	MMatrix *MYmatricesArray = 0; //A MOI je le desallouerai 
    	dataArray = AiNodeGetArray(handle, "matrix");
    	if (dataArray->data != NULL)
    	{
    		matricesArray = (MMatrix*)dataArray->data;
    	}
    	else
    	{
    		MYmatricesArray = new MMatrix[mMotionKeys]; // c'est mon mien!
    		matricesArray = MYmatricesArray ; // c'est sur matricesArray  qu'on travaille, je le "prete"
    		initialisation = true;
    	}
     
     
    ...
     
    delete [] MYmatricesArray; // c'etait le mien je le nettoie. Si je n'avais rien créé, delete [] 0 est parfaitement legal!

  13. #13
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 766
    Par défaut
    Salut,

    Désolé pour le délai de réponse, j'avais dû passer sur autre chose.

    En fait, pour la désallocation, je dois utiliser

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    if (initialisation == TRUE)
        delete [] MYmatricesArray;
    Si j'omets la condition, ça plante.

Discussions similaires

  1. QTableWidget récalcitrant qui provoque un plantage
    Par François Fontaine dans le forum Débuter
    Réponses: 4
    Dernier message: 03/07/2012, 19h10
  2. Réponses: 17
    Dernier message: 12/07/2011, 15h25
  3. delete provoque erreur heap
    Par kouillo dans le forum Débuter
    Réponses: 6
    Dernier message: 12/04/2011, 18h47
  4. Réponses: 1
    Dernier message: 14/12/2009, 22h13
  5. une requête SELECT INTO provoque un plantage sous Access
    Par Invité dans le forum Requêtes et SQL.
    Réponses: 3
    Dernier message: 29/12/2005, 11h35

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