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 :

Plantage en débug et pas en Release (MSVC 2003)


Sujet :

C++

  1. #1
    Membre éclairé
    Avatar de Floréal
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    456
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 456
    Points : 849
    Points
    849
    Par défaut Plantage en débug et pas en Release (MSVC 2003)
    Bonjour,
    Je travaille à l'évolution d'un projet, et pour cela j'ai du ajouter des données membres à une classe.
    Depuis quelques temps j'observe un phénomène assez étrange.
    En effet mon application plante lorsque je l'exécute en mode Debug (Buffer overflow), et fonctionne correctement en mode Release.
    Aprèsplusieurs tests je me suis rendu compte que les plantages survenaient que lorsque j'ai ajouté une donnée membre (un objet) à une certaine classe. Pourtant le plantage survient où les classes que j'ai modifiées n'interviennet pas.
    Comme il s'agissait de buffer overflow j'ai de suite pensé à de la récursivité, mais dans le code C++ je ne vois rien. Par contre en exécutant pas à pas le morceau de code incriminé, il passe dans de l'assembleur dont je n'ai pas la maitrise, mais je peux voir qu'il boucle.
    Le plantage à lieux lors de l'appel d'une fonction (le programme tente de l'appeler semble-t'il, mais n'y rentre pas). Le buffer overflow survient dans le fichier chkstk.asm (fourni par Miscrosoft), à la ligne 91.
    Mon projet est développé sous VS2003 (Microsoft Visual C++ .NET 69526-335-0000007-1806) avec des MFC.
    Je précise aussi que je n'ai jamais fait de MFC avant, et que certaines précautions à prendre on pu m'échapper.
    Avez vous déjà été confronté à ce problème?
    Si oui, vous en êtes vous sortis, et comment?
    Je vous remercie par avance de votre aide.
    Ancien membre du projet "Le Dernier Âge".

  2. #2
    Membre habitué
    Profil pro
    Inscrit en
    Janvier 2008
    Messages
    126
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2008
    Messages : 126
    Points : 149
    Points
    149
    Par défaut
    Bonjour,

    As-tu vérifié que les options de ton vcproj sont rigoureusement les mêmes en release et en debug.

    Sinon, je crois que j'ai déjà rencontré le problème que j'avais "résolu" (contourné) en remplaçant mes déclarations statiques de tableaux par des allocations dynamiques (en utilisant explicitement new).
    Exprimé autrement, j'avais contourné les limites de la pile par une allocation dynamique.

    En espérant que cela t'inspire,
    Cordialement,
    A.

    PS : Utilises-tu des ASSERT en debug ? Si oui, peut-être chercher dans cette direction...
    Un ordinateur fait au bas mot 1 million d'opérations à la seconde, mais il n'a que ça à penser, aussi. (brèves de comptoirs, JM.Gourio)


  3. #3
    Membre éclairé
    Avatar de Floréal
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    456
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 456
    Points : 849
    Points
    849
    Par défaut
    Ce que tu me dis au sujet des tableaux va m'être utile, car en effet dans la classe que j'ai ajouté j'utilise des tableaux statiques (de int).
    Pour les options de configuration, elles ne sont pas identiques, mais comme ce n'est pas moi qui ai fondé ce projet j'hésite à y toucher, d'autant que je ne le maitrise pas dans sa globalité.
    En ce qui concerne les ASSERT(), je n'en ai pas mis dans mon code.
    Ancien membre du projet "Le Dernier Âge".

  4. #4
    Membre chevronné
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 33
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Points : 2 205
    Points
    2 205
    Par défaut
    oublie les tableaux dynamiques C-like et passe aux vectors..


    Sinon pour le sujet principal : sans le code on va pas pouvoir dire grand chose.
    "Hardcoded types are to generic code what magic constants are to regular code." --A. Alexandrescu

  5. #5
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    J'ai l'impression que tu confonds buffer overflow (dépassement des limites d'un tableau, généralement, écriture de trop de caractères dans une chaîne de taille fixe), et stack overflow (débordement de pile, soit par allocation sur la pile d'un tableau trop grand, soit par récursivité infinie).

    Sinon, s'il s'agit bien d'un buffer overflow, il y a des chances qu'il existe en release mais ne soit pas détecté. Nettoie bien ton projet, cela dit, et si tu mélanges des libs debug/release (ça peut arriver quand on ne fait pas attention aux options du projet), il y a toutes les chances que ça vienne de là (il arrive que des programmeurs fassent des structures qui ne font pas la même taille en debug et en release).

  6. #6
    Membre éclairé
    Avatar de Floréal
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    456
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 456
    Points : 849
    Points
    849
    Par défaut
    En ce qui concerne les tableaux je préfère les utiliser parce que je connais déjà la taille de ces derniers, et j'ai déjà tenté d'utiliser des vecteurs avec les mfc et comment dire... ça ne voulait plus compiler.
    Et sinon pour white_tentacle: En effet c'est bien d'un stack overflow dont il s'agit, Au temps pour moi.
    Je crois que je vais tenter la solution d'agamitsudo.
    Ancien membre du projet "Le Dernier Âge".

  7. #7
    Membre éclairé
    Avatar de Floréal
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    456
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 456
    Points : 849
    Points
    849
    Par défaut
    Verdict: La solution proposée par agamitsudo a résolu mon problème. Un grand merci à toi, et aux autres pour leur contribution aussi.
    Ancien membre du projet "Le Dernier Âge".

  8. #8
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    À mon avis, tu as remplacé un problème par un autre.

    C'est quand même étonnant un stack overflow juste pour l'emploi de tableau. Soit tu alloues vraiment de gros tableaux (auquel cas, effectivement, il faut éviter la pile), soit tu as quand même pas mal de récursion avec allocation d'un nouveau petit tableau à chaque fois.

    Je ne serais pas étonné que tu puisses gagner beaucoup à réutiliser tes tableaux plutôt qu'à les réallouer.

  9. #9
    Membre éclairé
    Avatar de Floréal
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    456
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 456
    Points : 849
    Points
    849
    Par défaut
    Je ne détecte pas de comportement suspect de l'application pour l'instant. Et pas de fuite de mémoire non plus.
    Mon hypothèse me semble capillotractée mais je me demande si la gestion de la pile en Debug n'est pas différente de celle en Release (peut être à cause d'option de compilation/debug), sous VS2003, mais bon je ne suis pas un expert en produits microsoft.
    Ancien membre du projet "Le Dernier Âge".

  10. #10
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Floréal Voir le message
    Je ne détecte pas de comportement suspect de l'application pour l'instant. Et pas de fuite de mémoire non plus.
    Mon hypothèse me semble capillotractée mais je me demande si la gestion de la pile en Debug n'est pas différente de celle en Release (peut être à cause d'option de compilation/debug), sous VS2003, mais bon je ne suis pas un expert en produits microsoft.
    La seule différence est peut être dans la taille de la pile entre une version Release et debug. Cela peut se vérifier dans les options (de link de mémoire) de ton projet.
    A non, autre chose. En release, je ne pense pas que les méthodes de vérification d'intégrité de la pile soit activées (à confirmer). Donc, il est possible que tu aies un écrasement minime sans conséquence immédiatement visible : en release ça passe inaperçu, en Debug... chkasm te signale ton bug.

    Citation Envoyé par Floréal Voir le message
    chkstk.asm
    Ca peut être un problème d'écrasement : tu as déclaré un tableau de N et tu adresse N+i. Typiquement un indice qui varie de 1 à N et non de 0 à N-1. Si tu passes avec une allocation dynamique, le problème existe toujours mais peut être masqué si tu écrases une zone 'neutre' (i.e. sans effet visible). Mais tu te crées une bombe à retardement. Principe de Peters : le jour de la livraison/recette client, ce bug va réapparaître...
    Je ne peux que te conseiller de bien comprendre pourquoi tu avais ton erreur précédemment :
    1/ Tu allouais un tableau trop important sur la pile -> alors OK, l'allocation dynamique est une bonne solution (et std::vector l'aurait fait pour toi )
    2/ Tu écrases ta pile par un mauvais adressage -> alors là, il vaut mieux corriger le problème et laisser ton tableau sur la pile.


    [EDIT] : plus je relis le fil, plus j'ai tendance à penser que tu as un problème d'écrasement de ta pile : tu vas une ou quelques cases trop loin dans ton tableau.

  11. #11
    Membre éclairé
    Avatar de Floréal
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    456
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 456
    Points : 849
    Points
    849
    Par défaut
    Mes tableaux ont respectivement une taille de de 256, 240, 10, et 4 et je n'adresse JAMAIS des emplacement dans mes tableaux supérieurs ou égaux à ceux que j'ai donnés (où que je regarde dans le code ou intervient ma classe). C'est bien évidemment la première chose que j'ai vérifiée avant de poster un message ici.
    Et je viens d'ailleurs de revérifier cela (débugueur à l'appui), en écrivant ce message.
    Je crois vraiment que c'est un problème d'option de compilation et de taille de la pile.
    Ancien membre du projet "Le Dernier Âge".

  12. #12
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Ce sont des tailles trop petites pour exploser la pile (sauf si récursivité bien sur). Ce ne sont peut être pas les tableaux, mais visiblement tu écris quelques octets trop loin sur ta pile...
    Ca peut être aussi un problème de convention d'appel : un .h qui mentionne une fonction en __stdcall alors que l'implémentation est en __cdecl. Beaucoup plus rare car en général détecté au link.

  13. #13
    Membre éclairé
    Avatar de Floréal
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    456
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 456
    Points : 849
    Points
    849
    Par défaut
    Ma foi, je n'ai utilisé ni l'un ni l'autre dans la déclaration de ma classe:
    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
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    #pragma once
    #include <CString>
     
    class Reference : public CObject {
    	DECLARE_SERIAL( Reference )
    	//Données brutes
    	int *m_teinte, *m_niveauGris;
     
    	//données après traitement
    	int *m_teinteEch, *m_niveauGrisEch;
    	int m_blanc, m_noir;
    	int m_nbPixelGris, m_nbPixelChromatiques;
     
    	enum hue_limits {
    		red_orange = 8,
    		orange_yellow = 30,
    		yellow_green = 53,
    		green_turquoise = 98,
    		turquoise_cyan = 109,
    		cyan_azur = 135,
    		azur_blue = 151,
    		blue_violet = 170,
    		violet_magenta = 190,
    		magenta_red = 218
    	};
    public:
    	Reference(void);
    	~Reference(void);
    	inline Reference(const Reference &source) {
    		m_teinte = new int[TAILLE_TEINTE];
    		m_teinteEch = new int[10];
    		m_niveauGris = new int[TAILLE_NIVEAU_GRIS];
    		m_niveauGrisEch = new int[4];
    		*this = source;
    	}
     
    	inline Reference& operator=(const Reference& ref) {
    		if (this == &ref) return *this;
    		setTeinte(ref.m_teinte);
    		setNiveauGris(ref.m_niveauGris);
    		return *this;
    	}
     
    	//operations
    	double intersection(const Reference& autre) const;
    	CString toString();
     
    	//itérateurs (lecture seule)
    	inline const int* teinte() const { return m_teinte; };
    	inline const int* niveauGris() const { return m_niveauGris; };
     
    	//accesseurs
    	void setTeinte(const int *teintes); //int[240]
    	void setNiveauGris(const int* niveauGris); //int[256]
    	inline int nbPixel() const { return m_nbPixelGris + m_nbPixelChromatiques; }
    	virtual void Serialize(CArchive& ar);
     
    	friend bool operator==(const Reference& lhs, const Reference& rhs);
    	static const int TAILLE_TEINTE = 240;
    	static const int TAILLE_NIVEAU_GRIS = 256;
    protected:
    	//initialisation
    	void initialize();
    	void traitementInterneTeintes();
    	void traitementInterneNiveauGris();
    };
     
    inline bool operator==(const Reference& lhs, const Reference& rhs) {
    	if (&lhs == &rhs) return true;
    	for (int i = 0; i < 240; ++i) if (lhs.m_teinte[i] != rhs.m_teinte[i]) return false;
    	for (int i = 0; i < 256; ++i) if (lhs.m_niveauGris[i] != rhs.m_niveauGris[i]) return false;
    	return true;
    }
     
    template <class T>
    T accumulate(const T* ptr, const int begin, const int end, const T& value) {
    	T retour = value;
    	for (int i = begin; i < end; ++i) {
    		retour += ptr[i];
    	}
    	return retour;
    };
    Et voici mon implémentation, attention accumulate() n'est pas pas celui de la stl:
    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
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    #include "stdafx.h"
    #include "Reference.h"
    #include <sstream>
    #ifdef _DEBUG
    #include <fstream>
    #endif
     
     
    using namespace std;
     
    IMPLEMENT_SERIAL(Reference, CObject, 0)
     
    Reference::Reference(void)
    {
    	m_teinte = new int[TAILLE_TEINTE];
    	m_teinteEch = new int[TAILLE_TEINTE_ECH];
    	m_niveauGris = new int[TAILLE_NIVEAU_GRIS];
    	m_niveauGrisEch = new int[TAILLE_NIVEAU_GRIS_ECH];
    	initialize();
    }
     
    Reference::~Reference(void)
    {
    	delete [] m_teinte;
    	delete [] m_teinteEch;
    	delete [] m_niveauGris;
    	delete [] m_niveauGrisEch;
    }
     
    void Reference::initialize()
    {
    	for (int i = 0; i < TAILLE_NIVEAU_GRIS; ++i) m_niveauGris[i] = 0;
    	for (int i = 0; i < TAILLE_TEINTE; ++i) m_teinte[i] = 0;
    	for (int i = 0; i < TAILLE_NIVEAU_GRIS_ECH; ++i) m_niveauGrisEch[i] = 0;
    	for (int i = 0; i < TAILLE_TEINTE_ECH; ++i) m_teinteEch[i] = 0;
    	m_blanc = 0;
    	m_noir = 0;
    	m_nbPixelChromatiques = 0;
    	m_nbPixelGris = 0;
    }
     
    void Reference::traitementInterneTeintes()
    {
    	m_teinteEch[0] = accumulate(teinte(), 0, red_orange, 0) + accumulate(teinte(), magenta_red, TAILLE_TEINTE, 0);
    	m_teinteEch[1] = accumulate(teinte(), red_orange, orange_yellow, 0);
    	m_teinteEch[2] = accumulate(teinte(), orange_yellow, yellow_green, 0);
    	m_teinteEch[3] = accumulate(teinte(), yellow_green, green_turquoise, 0);
    	m_teinteEch[4] = accumulate(teinte(), green_turquoise, turquoise_cyan, 0);
    	m_teinteEch[5] = accumulate(teinte(), turquoise_cyan, cyan_azur, 0);
    	m_teinteEch[6] = accumulate(teinte(), cyan_azur, azur_blue, 0);
    	m_teinteEch[7] = accumulate(teinte(), azur_blue, blue_violet, 0);
    	m_teinteEch[8] = accumulate(teinte(), blue_violet, violet_magenta, 0);
    	m_teinteEch[9] = accumulate(teinte(), violet_magenta, magenta_red, 0);
    	m_nbPixelChromatiques = accumulate(m_teinteEch, 0, TAILLE_TEINTE_ECH, 0);
    }
     
    void Reference::traitementInterneNiveauGris()
    {
    	m_noir = accumulate(niveauGris(), 0, 64, 0);
    	m_blanc = accumulate(niveauGris(), 192, TAILLE_NIVEAU_GRIS, 0);
    	m_niveauGrisEch[0] = accumulate(niveauGris(), 64, 96, 0);
    	m_niveauGrisEch[1] = accumulate(niveauGris(), 96, 128, 0);
    	m_niveauGrisEch[2] = accumulate(niveauGris(), 128, 160, 0);
    	m_niveauGrisEch[3] = accumulate(niveauGris(), 160, 192, 0);
    	m_nbPixelGris = accumulate(m_niveauGrisEch, 0, TAILLE_NIVEAU_GRIS_ECH, m_noir + m_blanc);
    }
     
    double Reference::intersection(const Reference& autre) const
    {
    	if (nbPixel() == 0 || autre.nbPixel() == 0) return 0;
    	double cumul = 0;
    	for (int i = 0; i < TAILLE_TEINTE_ECH; ++i)
    	{
    		cumul += min(m_teinteEch[i], double(autre.m_teinteEch[i]) * double(m_nbPixelChromatiques + m_nbPixelGris) / double(autre.m_nbPixelChromatiques + autre.m_nbPixelGris) );
    	}
    	for (int i = 0; i < TAILLE_NIVEAU_GRIS_ECH; ++i)
    	{
    		cumul += min(m_niveauGrisEch[i], double(autre.m_niveauGrisEch[i]) * double(m_nbPixelChromatiques + m_nbPixelGris) / double(autre.m_nbPixelChromatiques + autre.m_nbPixelGris) );
    	}
    	cumul += min(m_noir, autre.m_noir * double(m_nbPixelChromatiques + m_nbPixelGris) / double(autre.m_nbPixelChromatiques + autre.m_nbPixelGris));
    	cumul += min(m_blanc, autre.m_blanc * double(m_nbPixelChromatiques + m_nbPixelGris) / double(autre.m_nbPixelChromatiques + autre.m_nbPixelGris));
    	return cumul / double(m_nbPixelChromatiques + m_nbPixelGris);
    }
     
    void Reference::setTeinte(const int* teintes) {
    	for (int i = 0; i < TAILLE_TEINTE; ++i) {
    		m_teinte[i] = teintes[i];
    	}
    	traitementInterneTeintes();
    }
     
    void Reference::setNiveauGris(const int* niveauGris) {
    	for (int i = 0; i < TAILLE_NIVEAU_GRIS; ++i) {
    		m_niveauGris[i] = niveauGris[i];
    	}
    	traitementInterneNiveauGris();
    }
     
    CString Reference::toString() {
    	ostringstream oss117;
    	oss117 << "t(";
    	for (int i = 0; i < TAILLE_TEINTE_ECH; ++i) {
    		if (i != 0) oss117 << ";";
    		oss117 << m_teinteEch[i];
    	}
    	oss117 << "), g(";
    	for (int i = 0; i < TAILLE_NIVEAU_GRIS_ECH; ++i) {
    		if (i != 0) oss117 << ";";
    		oss117 << m_niveauGrisEch[i];
    	}
    	oss117 << "), b:" << m_blanc << " n:" << m_noir;
    	return CString(oss117.str().c_str());
    }
     
    void Reference::Serialize(CArchive &ar) {
    	if (ar.IsStoring()) {
    		for (int i = 0; i < TAILLE_TEINTE; ++i) ar << m_teinte[i];
    		for (int i = 0; i < TAILLE_NIVEAU_GRIS ; ++i) ar << m_niveauGris[i];
    	} else {
    		for (int i = 0; i < TAILLE_TEINTE; ++i) ar >> m_teinte[i];
    		for (int i = 0; i < TAILLE_NIVEAU_GRIS ; ++i) ar >> m_niveauGris[i];
    		traitementInterneNiveauGris();
    		traitementInterneTeintes();
    	}
    }
    J'utilise les bornes que j'ai définies en const static public partout ailleurs (l'échantillonnage ne me servant qu'à faire des comparaisons, et n'est donc utile qu'en interne. C'est la raison pour laquelle les constantes se terminant par _ECH sont protected).
    Je suis tout de même inquiet par cette histoire de "bug invisible".
    Ancien membre du projet "Le Dernier Âge".

  14. #14
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Dans quelle fonction ça plante et as-tu le code de accumulate ?

  15. #15
    Membre éclairé
    Avatar de Floréal
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    456
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 456
    Points : 849
    Points
    849
    Par défaut
    ça plantait dans une portion du code qui n'a rien avoir avec ma classe, et que d'ailleurs je n'ai pas touchée, ou plutôt qui n'a pas d'influence directe: Il s'agissait du passage d'un pointeur sur une instance de classe, casté en void*; cette classe contient des instances de classe C1 qui contient des instances de classe C2 ... qui contient des instances de classe Cn contenant une Reference (colorimétrique).
    On m'a garanti que le code (du projet) avant mon interversion était correct.
    Le code de accumulate est dans l'interface de Référence (je sais, il faudrait que je sépare ça dans un autre fichier, mais pour l'instant ce n'est pas en rapport avec le problème actuel), ça itère seulement sur mon tableau entre begin et end (passés en paramètres).
    Ancien membre du projet "Le Dernier Âge".

  16. #16
    Membre émérite
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Points : 2 799
    Points
    2 799
    Par défaut
    L'objet Reference subit une sérieuse cure d'amaigrissement en allouant dynamiquement les tableaux.

    Tu pourrais donner sizeof(Reference) avant et après ta modif ? On parle de tableaux d'int, donc la taille doit pas être loin des 2ko avant ta modif.

    Si tu en alloues beaucoup sur la pile, ça peut effectivement péter ta pile.

  17. #17
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Avec visual, la taille de la pile par défaut est de 1Mo. Ca se modifie dans les options du projet : éditeur de liens/Système => Taille de la réserve de Pile.

  18. #18
    Membre éclairé
    Avatar de Floréal
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    456
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 456
    Points : 849
    Points
    849
    Par défaut
    sizeof(Reference) me donne 2056 (octets j'imagine). Oui, je peux donc dire que je dépasse largement le Mega Octet de la pile, vu le nombre de référence que je peux avoir en même temps.
    Vu que les test que je fais ne se font que sur un tout petit volume de donné comparé aux conditions réelles, je préfère allouer tout ça en dynamique.
    Sinon avez vous vu des problèmes dans mon code, qui m'auraient échapé?
    Ancien membre du projet "Le Dernier Âge".

  19. #19
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par Floréal Voir le message
    sizeof(Reference) me donne 2056 (octets j'imagine). Oui, je peux donc dire que je dépasse largement le Mega Octet de la pile, vu le nombre de référence que je peux avoir en même temps.
    Tu peux changer les paramètres de la pile pour voir si le problème venait de là.

    Citation Envoyé par Floréal Voir le message
    Sinon avez vous vu des problèmes dans mon code, qui m'auraient échapé?
    Tu ne gère pas la possibilité d'une exception dans tes constructeurs rendant ainsi possible la perte de mémoire si une exception est levée -> pointeurs intelligents
    Tu gères parfois les tailles avec des constantes (TAILLE_TEINTE) et d'autres fois avec des chiffres ([10])-> supprime les chiffres en dur. D'ailleurs même quand il ne s'agit pas des bornes de tes tableaux : évite les constantes en dur.

  20. #20
    Membre éclairé
    Avatar de Floréal
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    456
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 456
    Points : 849
    Points
    849
    Par défaut
    J'ai pensé à utiliser les pointeurs intelligents aussi, seulement, je ne peut hélas pas utiliser de librairies les implémentant (et je ne suis même pas sur d'avoir auto_ptr, dans VS2003, de toute façon je les fuis comme la peste ceux là, à cause des swaps intempestifs), j'ai donc plutôt opté pour ceci:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    try {
     //creation des ptrs
    } catch (...) {
     //suppression des ptrs
     throw;
    }
    J'ai aussi remplacé mes chiffres par des membres d'énumérations, pour l'accès aux différentes "cases" des tableaux.
    Ancien membre du projet "Le Dernier Âge".

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. Fonctionne en Debug mais pas en Release
    Par Baud10 dans le forum MFC
    Réponses: 23
    Dernier message: 04/02/2008, 15h17
  2. Réponses: 3
    Dernier message: 16/01/2008, 10h07
  3. [Surnaturel] Une fonction qui marche en débug, pas en release
    Par 10_GOTO_10 dans le forum C++Builder
    Réponses: 6
    Dernier message: 04/07/2006, 14h22
  4. Réponses: 12
    Dernier message: 15/02/2005, 15h34
  5. regsvr32 failed en debug mais pas en release
    Par afan dans le forum DirectX
    Réponses: 1
    Dernier message: 09/06/2004, 10h32

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