crash inexpliqué sur 'new'
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:
Code:
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"; |
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).
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é...
Code:
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;
} |
Merci pour toute idée qui me permettrait d'avancer !