Question

J'ai un programme dans lequel, en partie pour l'enregistrement d'informations, je sortie les noms de certaines classes comme ils sont utilisés (j'ajouter spécifiquement une entrée dans un journal disant le long des lignes de Messages::CSomeClass transmitted to 127.0.0.1). Je le fais avec un code similaire à ce qui suit:

std::string getMessageName(void) const {
    return std::string(typeid(*this).name());
}

Et oui, avant les points de quelqu'un dehors, je me rends compte que la sortie de typeinfo::name est mise en œuvre spécifique.

Selon MSDN

La fonction de l'élément de type_info::name renvoie un const char* à une chaîne de caractères terminée par null représentant le nom lisible par l'homme du type. La mémoire pointée est mis en cache et ne doit jamais être directement désallouée.

Cependant, quand je quitte mon programme dans le débogueur, toute utilisation « nouvelle » de spectacles de typeinfo::name() comme une fuite de mémoire. Si je sortie les informations pour 2 classes, je reçois 2 fuites de mémoire, et ainsi de suite. Ceci laisse présager que les données mises en cache est de ne jamais être libéré. ??

Bien que ce n'est pas un problème majeur, il semble désordonnée, et après une longue session de débogage, il pourrait facilement cacher les fuites de mémoire d'origine.

J'ai regardé autour et a trouvé des informations utiles (une réponse SO donne des informations intéressantes sur comment typeinfo peut être mis en œuvre ), mais je me demande si cette mémoire devrait normalement être libéré par le système, ou s'il y a quelque chose que je peux faire pour « pas d'avis » les fuites lors du débogage.

J'ai un plan de sauvegarde, qui consiste à coder la méthode getMessageName moi-même et ne pas compter sur typeinfo::name, mais je voudrais savoir quand même s'il y a quelque chose que j'ai raté.

Était-ce utile?

La solution

Une autre solution consiste à corriger le problème sous-jacent. Ce n'est pas vraiment une fuite de mémoire, juste un faux rapport. Les blocs de mémoire alloués à la chaîne tyepinfo () et le nom () sont affectés au type de bloc erroné. Il est sans doute pas une bonne idée de « libre » cette mémoire, car une tentative sera faite par le CRT pour le libérer à nouveau. Les bonnes nouvelles sont ce a finalement été fixé à VS2012 (_MSC_VER 1700 +).

Étant donné que cela ne concerne que construit _DEBUG, ce qui suit peut être une solution plus sûre. La fonction _FixTypeInfoBlockUse () doit être appelé comme mentionné ci-dessus, juste avant la sortie du point d'entrée du module (principal, WinMain, etc.).

#if defined(_DEBUG) && (_MSC_VER >= 1000 && _MSC_VER <= 1699)
//
// Debug memory block header:
//    o  Borrowed from the Microsoft CRT to fix the false "memory leak" report
//       when using typeinfo 'name' accessor in a _DEBUG build of the library.  
//
struct _CrtMemBlockHeader
   {
   struct _CrtMemBlockHeader * pBlockHeaderNext;
   struct _CrtMemBlockHeader * pBlockHeaderPrev;
   char *                      szFileName;
   int                         nLine;
   #ifdef _WIN64
   int                         nBlockUse;
   size_t                      nDataSize;
   #else
   size_t                      nDataSize;
   int                         nBlockUse;
   #endif
   long                        lRequest;
   unsigned char               gap[4];
   };

static void __cdecl _FixTypeInfoBlockUse(void)
   {
   __type_info_node* pNode = __type_info_root_node._Next;

   while(pNode != NULL)
      {
      __type_info_node* pNext = pNode->_Next;

      (((_CrtMemBlockHeader*)pNode) - 1)->nBlockUse = _CRT_BLOCK;

      if (pNode->_MemPtr != NULL)
         (((_CrtMemBlockHeader*)pNode->_MemPtr) - 1)->nBlockUse = _CRT_BLOCK;

      pNode = pNext;
      }
   }

#endif//defined(_DEBUG) && (_MSC_VER >= 1000 && _MSC_VER <= 1699)
scroll top