Bonjour,
J'ai un crash inexpliqué dans mon code, je pensais être un cador en C++ ;-), et je me retrouve à poil, complètement désarmé.
Si l'un de vous avait une idée, pas forcemment pour trouver le bug, mais des pistes pour continuer mes investigations...
Le contexte:
C++ & STL, sous Windows XP, compilé avec Mingw/GCC
Le code:
J'ai une classe 'BIT_VECTOR' qui est équipée "toutes options":
(constructeur, constructeur de copie, destructeur, opérateur d'affectation, etc...)
et qui fait de l'allocation dynamique (voir plus loin).
Quand je la teste individuellement, tout semble aller pour le mieux.
Quand je l'utilise dans mon applicatif, j'ai systématiquement un plantage, et Windows qui râle:
soit "XXXX.exe a rencontré un problème, etc",
soit "Erreur d'application:L'instruction à "0x7cc9..." emploie l'adresse mémoire "0xaddd..", la mémoire ne peut pas être "read" "
(Pour moi ce dernier message ressemble for à une erreur liée à la STL)
En utilisant gdb (dont je ne sais pas bien me servir), le callstack me dit que je suis dans des fonctions de
"c:\windows\system32\ntdll.dll", ca commence par l'appel de "Ntdll!RtlpNtMakeTemporaryKey()", mais aucune fonction à moi n'apparait. Bref, pas grand chose d'intéressant.
En loggant (dans cerr/stderr, redirigé dans un fichier avec freopen) ce qui se passe un peu partout, j'observe que le plantage se produit (si le log est fidèle, au sens temporel...) lors de l'allocation dynamique dans le constructeur de copie.
C'est à dire, j'ai le code suivant:
J'ai ajouté le 'nothrow' pour être sûr que ça ne soit pas lié à une exception mal gérée (je ne les utilise pas dans mon code).
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 cerr << "Before new, NbIndex=" << NbIndex << endl; bits = new (nothrow) uint[NbIndex]; if( bits == 0 ) { cerr << "Allocation failed\n"; exit(0); } cerr << "After new\n";
Et le log affiche le "Before", et rien après. J'ai vérifié la valeur de NbIndex, et le 'uint' est défini par
typedef unsigned int uint;
Bref, qu'est ce qui pourrait faire planter 'new' ??? Ceci se produit dans une fonction qui vient empiler des objets de ce type dans un vecteur STL, avec push_back (et donc, en tout logique, appel du constr. de copie, et c'est là que ça plante).
Je suis un peu sec. J'ai pensé à un problème de corruption mémoire, mais ça ne devrait pas planter à cet endroit logiquement...
Quels sont les outils que je pourrais utiliser pour trouver ?
Ci-dessous des bouts de code (en virant les trucs lié au logging). Y'a rien de particulièrement inhabituel, mais bon, qui sait si un truc ne m'a pas échappé...
Merci pour toute idée qui me permettrait d'avancer !
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 class BIT_VECTOR { private: uchar NbBits; uchar NbDims; uint NbIndex; uint* bits; static uchar def_NbBits; ///< alloué et initialisé correctement static uchar def_NbDims; ///< dans le .cpp public: BIT_VECTOR( uchar NbDimensions=def_NbDims, uchar NbBitsPerDim=def_NbBits ); BIT_VECTOR( const BIT_VECTOR& bv ); ~BIT_VECTOR(); BIT_VECTOR& operator = ( const BIT_VECTOR& bv ); }; /// Constructor BIT_VECTOR::BIT_VECTOR( uchar NbDimensions, uchar NbBitsPerDim ) { NbBits = NbBitsPerDim; NbDims = NbDimensions; ComputeNbIndex(); bits = new (nothrow) uint[NbIndex]; if( bits == 0 ) { cerr << "Allocation failed\n"; exit(0); } for( uint i=0; i<NbIndex; i++ ) bits[i] = 0; } /// Copy-constructor BIT_VECTOR::BIT_VECTOR( const BIT_VECTOR& bv ) { NbBits = bv.NbBits; NbDims = bv.NbDims; NbIndex = bv.NbIndex; bits = new (nothrow) uint[NbIndex]; if( bits == 0 ) { cerr << "Allocation failed\n"; exit(0); } for( uint i=0; i<NbIndex; i++ ) { bits[i] = bv.bits[i]; } } /// Destructor BIT_VECTOR::~BIT_VECTOR() { delete[] bits; } /// Assignment operator BIT_VECTOR& BIT_VECTOR::operator = ( const BIT_VECTOR& bv ) { assert( bv.IsSameType( *this ) ); for( uint i=0; i<NbIndex; i++ ) bits[i] = bv.bits[i]; return *this; }
Partager