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 :

malloc instable ?


Sujet :

C++

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    97
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2002
    Messages : 97
    Points : 69
    Points
    69
    Par défaut malloc instable ?
    Bonjour,


    je viens ici pour comprendre pourquoi la fonction malloc pourrait me provoquer des erreurs d'executions.

    je m'explique :

    j'ai un code générant des tableaux de dimensions 1 et de dimensions 2 de manière dynamique. Ces tableaux font partis d'une classe que je nome AGO. Lors de l'utilisation du programme, je crée un objet de AGO qui crée dans son constructeur les tableaux voulus selon les dimensions passées en paramètres.

    A chaque utilisation, je recrée un nouvel objet AGO. A la première utilisation, il n'y a aucun problème. A la seconde utilisation, mon programme plante. En remontant dans le code, j'ai pu constater que les lignes contenant la fonction malloc en sont responsable.

    Le programme ne demande pas beaucoup de mémoire, au plus quelques ko par tableau, donc cela ne peut etre un débordement. (au fait je préviens que je suis un débutant du malloc).

    donc voici les deux lignes responsables :

    // on crée le vecteur de demande
    v = (signed int *) malloc(sizeof(signed int)*m);

    // on crée le vecteur d'erreur
    e = (signed int *) malloc(sizeof(signed int)*m);
    la variable m a toujours la même valeur. (donc là ce n'est pas du dynamique mais c'est juste pour vérifier si je peux faire plusieurs fois la même opération).

    Le plantage est significatif après une deuxième création d'objet AGO voir parfois à la troisième ou quatrième. Par contre, avec les lignes suivantes du code :

    a = (bool**) malloc(n * sizeof(bool*));
    for(unsigned int i = 0; i < n; i++)
    a[i] = (bool*) malloc(m * sizeof(bool));


    le plantage se fait obligatoirement à la seconde fois. (la variable n est fixé).

    Pourriez vous me conseillez concernant la fonction malloc etc. Cela me pose quelques problèmes pour développer et cela m'ennuie d'avoir un programme instable.

    merci pour vos futures réponses !

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut clarifiez le programme "plante"!
    En général, c'est un peu plus bavard que "plante".
    Ca dit quoi?
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre chevronné
    Homme Profil pro
    edi
    Inscrit en
    Juin 2007
    Messages
    899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : edi

    Informations forums :
    Inscription : Juin 2007
    Messages : 899
    Points : 1 916
    Points
    1 916
    Par défaut
    malloc()/free() en C++ c'est le mal, new/delete c'est mieux

    Les std::vector aussi c'est bien.

    Faudrait voir quel est le message d'erreur que tu obtiens.

    Avec new[] et delete[] :

    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
    48
    49
    50
    51
    52
     
    #ifndef AHO_H
    #define AGO_H
     
    class AGO
    {
    private:
    	int* _V;
    	int size_v;
     
    	int* _E;
    	int size_e;
     
    	bool** _A;
    	int size_a1;
    	int size_a2;
    public:
    	AGO(int v, int e, int a1, int a2):
    	  _V(0), _E(0), _A(0), size_v(v), size_e(e), size_a1(a1), size_a2(a2)
    	{
    		_V = new int [size_v];
    		for(int i = 0; i < size_v; ++i)
    			_V[i] = 0;
     
    		_E = new int [size_e];
    		for(int i = 0; i < size_e; ++i)
    			_E[i] = 0;
     
    		_A = new bool*[size_a1];
    		for(int i =0; i < size_a1; ++i)
    		{
    			_A[i] = new bool[size_a2];
    			for(int j = 0; j < size_a2; ++j)
    				_A[i][j] = false;
    		}
    	}
     
    	~AGO()
    	{
    		for(int i = 0; i < size_a1; ++i)
    			delete[] _A[i];
    		delete[] _A;
     
    		delete[] _E;
     
    		delete[] _V;
    	}
     
    	/* Divers acesseurs et méthodes */
    };
     
    #endif

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    97
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2002
    Messages : 97
    Points : 69
    Points
    69
    Par défaut
    Et bien je viens juste de modifier mon code pour enlever les malloc. J'y ai donc mis des new à la place. Mais même plantage. Par contre, pour un quelconque message, je n'ai absolument rien. A part quand j'ai employé le debuggeur de wxdevcpp, il m'a mis une erreur de segmentation. (problème souvent du à des mauvais pointeurs mal gérés je suppose). Je cherche de ce coté là. Mais je ne maitrise vraiment pas le débuggeur (mea culpa).

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    je suspecterais plutôt un pb côté assignation dans a et a[i] que dans malloc, mais un coup de debugger devrait régler çà
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    97
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2002
    Messages : 97
    Points : 69
    Points
    69
    Par défaut
    Oui mais pourquoi cela marche pour la première fois, et non pour les fois suivantes ? C'est surtout cela ma question... Car tout fonctionne bien pour la première fois.

  7. #7
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    c'est pour répondre à ce genre de questions invraisemblable qu'on a inventé les debugger
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Membre régulier

    Profil pro
    Étudiant
    Inscrit en
    Juin 2006
    Messages
    78
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2006
    Messages : 78
    Points : 105
    Points
    105
    Par défaut
    Parce que la première fois tu tombe dans une page mémoire allouée au programme, les suivantes non ?
    "The worst errors I've ever seen do not came from no knowledge, but from having just the the right amount of it, too small to really understand what you're doing, but enough to think you did. That amount of knowledge, is evil."

  9. #9
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    97
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2002
    Messages : 97
    Points : 69
    Points
    69
    Par défaut
    Lorsque j'utilise les breakpoints du debugger, donc en faisant pas à pas l'execution, il n'y a pas de problème apparemment. Il fonctionne correctement.

  10. #10
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut chouette un Heisenbug!
    Jetez les breakpoints et remplacez les par des printf des adresses d'affectations
    &a[i], i, n
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  11. #11
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    97
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2002
    Messages : 97
    Points : 69
    Points
    69
    Par défaut
    Normalement, new doit se débrouiller pour trouver de l'espace mémoire, surtout que mon programme ne prend vraiment pas bcp (1Mo) et que j'ai suffisement de place. Donc normalement, il ne devrait pas avoir d'erreur d'allocation de mémoire.

  12. #12
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Il faudra qu'on m'explique pour continuer à utiliser new[] alors que la bonne solution à été donnée (std::vector).
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  13. #13
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Il est clair que la bonne solution est à base de vector. Il n'empêche qu'un malloc ne doit pas "planter" sans raisons. Un exemple complet qui reproduise le problème permettrait probablement de lui tordre le cou une bonne fois pour toute, avant de basculer vers la bonne solution l'esprit allégé.
    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.

  14. #14
    Membre du Club
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    97
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Juillet 2002
    Messages : 97
    Points : 69
    Points
    69
    Par défaut
    oui mais pour un vector n'est-il pas plus lent ? ou bien il n'est lent que pour la création, après, il est bon et efficace ?

  15. #15
    Rédacteur

    Avatar de Davidbrcz
    Homme Profil pro
    Ing Supaéro - Doctorant ONERA
    Inscrit en
    Juin 2006
    Messages
    2 307
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : Suisse

    Informations professionnelles :
    Activité : Ing Supaéro - Doctorant ONERA

    Informations forums :
    Inscription : Juin 2006
    Messages : 2 307
    Points : 4 732
    Points
    4 732
    Par défaut
    Du point de vue fanatique:
    std::vector c'est le bien !
    A la facon yoda :
    std::vector dans tes programmes tu utilisera !
    Nan le vector n'est guère (pas ?) plus lent qu'un tableau brut, mais avec des dizaines de fonctions en plus.

    PS: +1 à Loic.
    "Never use brute force in fighting an exponential." (Andrei Alexandrescu)

    Mes articles dont Conseils divers sur le C++
    Une très bonne doc sur le C++ (en) Why linux is better (fr)

  16. #16
    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 : 49
    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
    Points : 16 213
    Points
    16 213
    Par défaut
    Réponse courte : Non.

    Réponse longue :

    Il est plus lent qu'un tableau statique (mais ce n'est pas là ton cas, sinon std::tr1::array remplirait ce rôle), et peut dans certains cas être plus lent qu'un tableau variable C (pas disponible en C++, aucun équivalent en terme de performances).

    Il peut dans certains cas être plus lent qu'un tableau à la C alloué dynamiquement, s'il est mal utilisé (pas de reserve alors qu'on connais dès le début la taille finale, s'il est passé par copie à une fonction, options de compilations permettant de détecter des erreurs restant dans le code final...).

    Un tableau à la C alloué dynamiquement peut être plus lent s'il est mal utilisé, ce qui peut arriver facilement (mauvaise stratégie de croissance si la taille n'est pas connue dès le début (une bonne stratégie est relativement complexe à mettre en place)).

    Un vector est infiniment plus souple, simple, sûr. Les dés sont largement pipés en faveur de std::vector.
    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.

  17. #17
    Membre régulier

    Profil pro
    Étudiant
    Inscrit en
    Juin 2006
    Messages
    78
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2006
    Messages : 78
    Points : 105
    Points
    105
    Par défaut
    Citation Envoyé par JolyLoic Voir le message
    Les dés sont largement pipés en faveur de std::vector.
    Sous entendre qu'il y a une once de hasard dans ce choix est quelque peu pervers...
    "The worst errors I've ever seen do not came from no knowledge, but from having just the the right amount of it, too small to really understand what you're doing, but enough to think you did. That amount of knowledge, is evil."

  18. #18
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    malloc peut retourner un pointeur nul.
    Tu ne traites évidemment pas ce cas.
    Boost ftw

  19. #19
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par loufoque Voir le message
    malloc peut retourner un pointeur nul.
    Tu ne traites évidemment pas ce cas.

    Oui mais, originellement:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     a = (bool**) malloc(n * sizeof(bool*));
    for(unsigned int i = 0; i < n; i++)
    a[i] = (bool*) malloc(m * sizeof(bool));
    le plantage se fait obligatoirement à la seconde fois. (la variable n est fixé).
    Donc OK, s'il y avait des tests, nous pourrions ne pas nous poser de questions stupides, mais si nous faisons confiance à l'auteur çà plante lorsqu'on alloue a[1].
    Comme n ne devrait pas être modifié, c'est "strange".
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  20. #20
    Expert confirmé
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Décembre 2003
    Messages
    3 549
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

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

    Informations forums :
    Inscription : Décembre 2003
    Messages : 3 549
    Points : 4 625
    Points
    4 625
    Par défaut
    C'est quoi l'intérêt de faire ça, au fait, plutôt que d'allouer un bloc contigü de n x m bools ?
    Boost ftw

Discussions similaires

  1. Erreur windows lors du malloc
    Par Elessar dans le forum C
    Réponses: 5
    Dernier message: 16/12/2003, 08h53
  2. malloc et free
    Par barthelv dans le forum C
    Réponses: 3
    Dernier message: 22/07/2003, 18h34
  3. Pb : malloc qui marche une fois sur deux .... ?
    Par guillaume_pfr dans le forum C
    Réponses: 14
    Dernier message: 21/07/2003, 09h52
  4. Erreur de sgmentation avec malloc
    Par simonm dans le forum C
    Réponses: 5
    Dernier message: 27/02/2003, 08h29
  5. Réponses: 4
    Dernier message: 03/12/2002, 16h47

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