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

Langage C++ Discussion :

Erreur de corruption mémoire apres un "vector.resize"


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2010
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 17
    Par défaut Erreur de corruption mémoire apres un "vector.resize"
    Bonjour a tous et a toutes,

    Excusez moi pour les accent, je n'ai qu'un clavier qwerty, et excusez moi aussi pour mon faible niveau en language C++, c'est pour cette raison que je solicite votre aide et votre immense experience.

    Je travaille dans la physique subatomique, et j'ai concu un programme de simulation pour effectuer des interactions a N corps (genre : gestion des effets PhysX de nvidia). Ce programme utilise des calculs assez complexes, mais pour plus de facilite, je stocke, a chaque pas de temps, des tableaux dynamiques de donnees necessaires aux calculs.

    Sauf que : mon nombre de particules augmente au fur et a mesure par fission (c'est ce que je veux) : quand cela se produit j'obtiens une erreur :

    ***glibc detected*** malloc(): memory corruption (fast): 0x.........

    Cela veux dire que malgre la quasi-perfection de la STL, la fonction resize que j'utilise pour mes vector< vector<TYPE> > n'utilise pas correctement l'allocation memoire.

    Voila une "ebauche" du code que j'utilise :
    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
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
     
    Class SYSTEM
    {
        public :
             SYSTEM() {};
            ~SYSTEM() {};
     
            ... // quelques reglages de parametres.
     
        private :
            int n_particules;
     
            vector< vector<double> > A_ij;
            vector< vector<double> > B_ij;
     
            ...
     
            void calcul();
            void etape_1();
            void etape_2();
    }
     
    void SYSTEM::calcul()
    {
        n_particules = ...; // calcul.
    }
     
    void SYSTEM::etape_1()
    {
        A_ij.resize(n_particules, vector<double>(n_particules));
    }
     
    void SYSTEM::etape_2()
    {
        B_ij.resize(n_particules, vector<double>(n_particules));
    }
     
    int main()
    {
        SYSTEM system;
     
        system.calcul();
        system.etape_1();
        system.etape_2();
     
        return EXIT_SUCCESS;
    }
    En gros, si mon programme etait cette ebauche : des que n_particules changerais il effectuerait correctement le resize de A_ij, et il indiquerait le message d'erreur au niveau du resize de B_ij. C'est etrange, non ?

    Pourquoi le resize d'un vector contenu dans un objet comme tableau dynamique ferait de la corruption de memoire ?

    Si vous avez de l'experience vis-a-vis des memory corruption avec des vector.resize, je suis tres interesse par votre aide. Merci d'avoir lu ce message assez long.

  2. #2
    Membre Expert
    Avatar de Joel F
    Homme Profil pro
    Chercheur en informatique
    Inscrit en
    Septembre 2002
    Messages
    918
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Chercheur en informatique
    Secteur : Service public

    Informations forums :
    Inscription : Septembre 2002
    Messages : 918
    Par défaut
    que vaut ton n_particules ?
    Poste un code minimale compilable reproduisant l'erreur.

  3. #3
    Membre Expert
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Par défaut
    Bonjour,

    Citation Envoyé par Asohan Voir le message
    Cela veux dire que malgre la quasi-perfection de la STL, la fonction resize que j'utilise pour mes vector< vector<TYPE> > n'utilise pas correctement l'allocation memoire.
    ... ou que tu as fait une erreur dans ton code... les paris sont ouverts!

    Il est surtout important que tu envoies la partie du code qui manipule Aij et Bij.
    C'est a priori de là que vient le problème... ah oui j'ai parié!

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Août 2010
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 17
    Par défaut
    Eh ben oui !! Vous avez toujours raison c'est pas juste

    Bon j'ai perdu combien pour le pari ?

    Alors, mon probleme commence a s'eclaircir :
    - Il ne s'agit pas de la STL (ca paraissait evident, mais bon, on ne sait jamais),
    - il ne s'agit pas de la valeur de n-particule ou d'une autre variable (le calcul est bon et le debugger me donne bien les bonnes valeurs pour mon gros programme)

    J'ai teste un code minimal et aussi mon programme apres une grosse cure de Slim Fast, mais du coup je n'ai plus mon erreur

    Neanmoins j'ai toujours une erreur glibc memory corruption pour mon code complet. De par votre experience qu'est-ce que ca peut etre autrement ?

    Lorsqu'il s'agit d'une segmentation fault ou bien d'une double free or corruption la je vois de quoi il s'agit et je corrige mon erreur, mais pour mon probleme, je ne vois pas du tout. Une idee ?

    PS : Je n'ai pas l'autorisation par mon labo de poster le code global librement, mais en revanche, je peux tres bien l'envoyer a quelqu'un par email, car je ne dispose pas d'outils de debuggage avances chez moi.

  5. #5
    Membre Expert
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Par défaut
    Bonjour,

    bon allez on annule les paris : je compatis pour le temps que tu vas passer à chercher l'erreur!

    Sinon, en "googlisant" glibc memory corruption, je suis tombé sur un début d'explication :
    http://ubuntuforums.org/showthread.php?t=774897

    En particulier, ce passage devrait te donner des pistes :
    A glibc memory corruption error usually means that your code overwrote some of the memory
    between the allocated ranges handed to you by malloc or calloc (or realloc).
    It can also be caused by continuing to access memory that you have freed,
    or freeing the same address twice, or freeing an address you never allocated.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Août 2010
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 17
    Par défaut
    Merci pour ta reponse, j'ai deja googler avant de poster mon message et j'ai vu la meme chose. C'est pour ca que j'accusais le resize.

    Je n'utilise aucun new ou delete. Je n'utilise que des variables temporaires toutes simples (float, int, unsigned int, ...). Par contre j'utilise des tableaux.
    Mais ce ne sont que des matrices carrees N x N qui, apres changement de N-->N', sont "resizees" a N' x N'.

    Sinon, en principe, lorsque l'on cree un objet tres simple dans une boucle, celui ci est detruit et desaloue a la fin de la boucle ? Je dis ca parce que j'ai cree l'objet particule qui me sert a trimbaler les caracteristiques et les fonction propres (methodes) de facon plus intuitives. J'utilise parfois des particule temporaires dans des boucles afin d'eviter de faire n'importe quoi sur mon vrai vector<particule>.
    Genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    for(int i=0 ; i<n_particules ; i++)
    {
        PARTICULE test_particule = particule[i];
     
        ... // calculs.
    }

  7. #7
    Membre Expert
    Homme Profil pro
    Chercheur
    Inscrit en
    Mars 2010
    Messages
    1 218
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Chercheur

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 218
    Par défaut
    Citation Envoyé par Asohan Voir le message
    Sinon, en principe, lorsque l'on cree un objet tres simple dans une boucle, celui ci est detruit et desaloue a la fin de la boucle ?
    Ca dépend.
    Pour une création statique entre deux accolades,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    {
    // ... du code ...
    Objet instance;
    // ... du code ...
    }
    instance sera détruit automatiquement à la fin des accolades.

    Par contre, pour une création dynamique,
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    {
    // ... du code ...
    Objet* instance=new Objet();
    // ... du code ...
    }
    instance ne sera pas détruit : c'est à toi de le faire en écrivant
    à un endroit du code, à l'intérieur ou à l'extérieur des accolades.

  8. #8
    Membre chevronné Avatar de seeme
    Profil pro
    Inscrit en
    Octobre 2005
    Messages
    430
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France

    Informations forums :
    Inscription : Octobre 2005
    Messages : 430
    Par défaut
    Citation Envoyé par Asohan Voir le message
    Merci pour ta reponse, j'ai deja googler avant de poster mon message et j'ai vu la meme chose. C'est pour ca que j'accusais le resize.

    Je n'utilise aucun new ou delete. Je n'utilise que des variables temporaires toutes simples (float, int, unsigned int, ...). Par contre j'utilise des tableaux.
    Mais ce ne sont que des matrices carrees N x N qui, apres changement de N-->N', sont "resizees" a N' x N'.

    Sinon, en principe, lorsque l'on cree un objet tres simple dans une boucle, celui ci est detruit et desaloue a la fin de la boucle ? Je dis ca parce que j'ai cree l'objet particule qui me sert a trimbaler les caracteristiques et les fonction propres (methodes) de facon plus intuitives. J'utilise parfois des particule temporaires dans des boucles afin d'eviter de faire n'importe quoi sur mon vrai vector<particule>.
    Genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    for(int i=0 ; i<n_particules ; i++)
    {
        PARTICULE test_particule = particule[i];
     
        ... // calculs.
    }

    Si tu as utilisé ces mémoires de manières statiques (sans new/alloc), elles seront détruite en sortie de bloc d'instruction.

  9. #9
    Rédacteur/Modérateur
    Avatar de JolyLoic
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2004
    Messages
    5 463
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 50
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2004
    Messages : 5 463
    Par défaut
    Citation Envoyé par Asohan Voir le message
    Mais ce ne sont que des matrices carrees N x N qui, apres changement de N-->N', sont "resizees" a N' x N'.
    Tu es au courant que d'après le code que tu nous as montré, ton "resize" transforme des matrices N*N en "matrices" dont les N premières lignes ont une taille N, et les N'-N dernières une taille N' :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Ex : Si N == 3 et N' == 5
    Avant :
    ***
    ***
    ***
     
    Après :
    ***
    ***
    ***
    *****
    *****
    Ma session aux Microsoft TechDays 2013 : Développer en natif avec C++11.
    Celle des Microsoft TechDays 2014 : Bonnes pratiques pour apprivoiser le C++11 avec Visual C++
    Et celle des Microsoft TechDays 2015 : Visual C++ 2015 : voyage à la découverte d'un nouveau monde
    Je donne des formations au C++ en entreprise, n'hésitez pas à me contacter.

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

Discussions similaires

  1. Vider la mémoire après utilisation d'une feuille excel
    Par snooopy007 dans le forum Access
    Réponses: 15
    Dernier message: 19/07/2006, 20h11
  2. [ImageMagick] Erreur liée à la mémoire lors de la création
    Par ehmppowa dans le forum Bibliothèques et frameworks
    Réponses: 13
    Dernier message: 07/03/2006, 13h28
  3. libération de la mémoire après traitement ?
    Par isachat666 dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 07/12/2005, 19h29
  4. Erreur sur le TNSListener après installation de 9iAS
    Par Patmane dans le forum Installation
    Réponses: 4
    Dernier message: 04/02/2004, 11h16

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