2010-01-18 5 views
2

Je reçois des erreurs d'allocation de mémoire (et un accident ultérieur) sur le code simplifié suivant:Trouver erreur d'allocation mémoire

std::wstring myKey = L"str_not_actually_constant"; 

MyType obj; 
Read(obj); 

std::map<std::wstring, MyType> myMap; 
myMap[myKey] = obj; // Sometimes allocation error (1) 
... 
Read(MyType& obj) 
{ 
    obj.member1 = ReadFromFuncThatMayBeProblem(); 
    obj.member2 = ReadFromFuncThatMayBeProblem(); // Sometimes allocation error (2) 
    /* more members */ 
} 
... 
void operator =(const MyType& source) 
{ 
    if(this != &source) 
    { 
    member1 = source.member1; // std::wstring 
    member2 = source.member2; // Usually (1) happen on the second member. // std::wstring 
    /* more members */ 
    } 
} 

Soit (1) ou (2) se produisent.

Maintenant, si je continue simplement sans tenir compte de l'erreur (avec le débogueur), la valeur est en effet entrée dans la carte.

Je ne sais pas si ReadFromFuncThatMayBeProblem() est le coupable mais c'est une fonction assez complexe que je ne peux pas me permettre ici.

De plus, il s'agit d'un code qui a fonctionné (ou du moins semblait fonctionner) avant que d'autres sections de l'application soient portées pour utiliser OpenSSL. Je ne sais pas si cela a pu avoir un effet ici, cependant. Alors, que puis-je faire pour retrouver cette erreur d'allocation, puisque je présume que le code ci-dessus n'est pas le problème?

Éditer: Informations supplémentaires: Il n'y a pas dtor pour MyType. Cependant, MyType a un membre de type SecondType qui a un membre void *. Ceci est en train d'être supprimé et annulé dans le destructeur de ce type. Le constructeur utilise m_pData = new std :: wstring (((std :: wstring) source.m_pData)); pour les cordes. (Et similaire pour les autres types de données). Cela pourrait-il être un problème? (delete static_cast < std :: wstring *> (m_pData);)

Les autres types de membres de MyType sont std :: wstring, unsigned long, bool, enum, structs (timeb entre eux) et SecondType.

+0

Avez-vous un test complet, un que nous pourrions essayer? – outis

+0

MyType contient-il des variables membres de pointeur? dans ce cas, copie ctor et opérateur d'affectation écrit correctement? – Naveen

+0

outis: Non, désolé. Je ne peux pas fournir cela. Naveen: Il n'y a pas de variables de membre de pointeur. –

Répondre

2

Enfin détecté l'erreur.

Nous utilisons la fonctionnalité ci-dessus dans le cadre d'une communication socket plus grande en utilisant OpenSSL (d'où la référence ci-dessus). Le socket écrivait des données et lisait des données selon la simplification du code ci-dessus.

La façon dont le socket a été lu était que nous réallouions la mémoire d'un tampon à un autre (en changeant la taille dynamiquement). En faisant cela, nous utilisons l'entrée du tampon et la taille que nous devrions développer. Le calcul de la taille utilisait modulo pour calculer le facteur de la redimensionnement. Cela a provoqué que le tampon soit trop grand ou trop petit pour s'adapter aux opérations suivantes. Deux jours de débogage pour changer un «%» en un «/».

Merci pour tout le soutien, cependant.

+0

J'ai le sentiment que vous n'utilisez pas d'assertions ou beaucoup de journalisation. Comment comptez-vous garder la bête de code sous votre laisse? –

+1

Nous utilisons des assertions et la journalisation. Nous n'avions tout simplement rien de tel dans ce cas ou dans cette partie-ci. Il semble que vous essayez de choisir un combat ... –

+0

+1 pour une erreur simple qui nécessite un effort disproportionné pour réparer. Bon à savoir, la programmation ne change jamais en son cœur. – outis

0

de quel type est-ce que ReadFromFuncThatMayBeProblem() renvoie? Renvoie-t-il une référence (const)? Si c'est le cas, l'objet est-il toujours valide après avoir quitté la portée de ReadFromFuncThatMayBeProblem()?

+0

Il retourne le type de membre (std :: wstring, long etc). (Non-const.) –