Double free or corruption

Signaler
Messages postés
90
Date d'inscription
samedi 23 novembre 2002
Statut
Membre
Dernière intervention
28 avril 2010
-
Messages postés
3833
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
11 juin 2021
-
Hello tout le monde,

voilà, j'ai un bête problème de pointeur dans mon code qui m'amène à une erreur de type
*** glibc detected *** ./percolation: double free or corruption (!prev): 0x09525138 ***

Voici les bribes utiles de mon code :

int *lat; //<- variable déclarée globalement

percolation::percolation(int seed, float proba, int N)
{
...
lat = new int[squareN]; //a l'initialisation de la classe, j'alloue la mémoire à ma variable
...
}

//A un moment, j'appelle la fonction suivante
int percolation::addToCluster(int i,int mainCluster,int * M,int k)
{
...
    lat[i] = lat[mainCluster]; //<- selon mes tests, c'est précisément à cause de cette ligne que l'erreur apparait.

    M[lat[i]]++;

    return k;
}

//naturellement, le destructeur de mon objet libère la mémoire
percolation::~percolation()
{
    delete [] lat;
}


Voila, ca fait un moment que je tourne en rond sur google, sans trouvé la solution à mon problème.

Si quelqu'un à une idée, je serais vraiment content.

Salutations.
BirD

3 réponses

Messages postés
3833
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
11 juin 2021
122
Pas mal de petit soucis:
- Variable globale: Aucune, absolument aucune raison d'avoir une variable global en C++. Ici, la variable devrait être un attribut de classe normal ou statique. Ou encore un singleton.
- int*: En C++ on a des conteneurs: std::vector, std::list, std::deque, etc... Rare sont les cas où ils ne sont pas à privilégier sur des "type*" du C.
- La fonction addToCluster est vraiment bizarre. Il y a sûrement moyen de l'architecturer d'une autre manière. Ici, ce n'est pas la question, mais ton code semble architecturé au hasard.

Répondons un peu plus à ta question:
Je pense que c'est un problème vicieux, mais très classique.

Imagine que j'ai l'objet suivant: percolation p;
Si je passe "p" par copie, au lieu de le passer par référence, ça peut poser un gros problème.

void f1(percolation p);
void f2(percolation& p);
void f3(percolation* p);

Ici, il n'y aura pas de problème pour f2 et f3. En revanche, pour f1, l'objet p est copié lors du passage en argument. Toute copie locale à une fonction étant détruite au sortir de celle-ci, ton objet p est détruit. La variable globale lat est alors détruite une première fois. L'objet originale, lors de sa destruction détruira une deuxième fois celle-ci, d'où l'erreur.

Bien évidemment, il me faut plus de code pour te le confirmer, mais j'ai l'intuition que c'est le problème :p

_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]
Messages postés
90
Date d'inscription
samedi 23 novembre 2002
Statut
Membre
Dernière intervention
28 avril 2010

Hello,

merci pour la réponse. Comme tu le vois, je suis pas super habitué au C++ et j'apprends un peu sur le tas...

En fait, quand je dis que j'ai déclaré ma variable globalement, c'est faut. Mon lat est un attribut de classe. De plus, selon ton conseil, j'ai modifié tous mes pointeurs en vecteur. Je connaissais pas ce type de truc... super puissant et tellement agréable.

Donc maintenant, le début de mon objet est comme ceci:
includes, etc
...
class percolation
{
private:
...
    vector lat;
...
public:
   
...

};


Mon problème persiste encore et toujours. J'ai fait encore quelques tests et j'avoue que c'est vraiment étrange. Mon vecteur lat est initialisé avec une certaine taille :
squareN = N * N;
lat.assign(squareN,0);

De tous les N que j'ai essayé, je reçois l'erreur seulement quand N = 5...

BirD
Messages postés
3833
Date d'inscription
dimanche 12 décembre 2004
Statut
Modérateur
Dernière intervention
11 juin 2021
122
Utiliser un std::vector ne résoudra pas ton problème si c'est celui que je t'ai décrit. Ça reste une bonne chose.

Pas vraiment le choix. Il va falloir que tu crées un mini exemple avec ton code, de manière à ce qu'il mette en avant ton erreur.
Si tu peux fournir un petit exemple qui compile et qui provoque cette erreur, il devrait être aisée d'identifier la source de l'erreur.
Si ton code n'est pas trop gros, tu peux aussi le poster, ça sera plus simple de t'aider.

_____________________________________________
Historique de mes créations, et quelques articles:[ http://0217021.free.fr/portfolio
http://0217021.free.fr/portfolio]