7
votes

Pourquoi un destructeur de suppression scalaire est-il appelé à la suite d'une suppression de vecteur sous Windows?

J'ai un code qui fuit sur Windows. Il fonctionne bien sur de nombreuses plates-formes UNIX et la fuite ne se produit que sur Windows. Le binaire est constitué d'EXE, de 1 dll et de 2 libs statiques. L'EXE relie à la fois la DLL et les Libs statiques, tandis que les Libs statiques sont également liés à la DLL. La fuite se produit dans le code EXE au lieu d'appeler à un vecteur Supprimer destructeurs, pour une raison quelconque, la suppression de la suppression progressive est appelée. Cela ne résulte que du premier objet de la matrice à supprimer, tandis que le reste de la matrice reste en mémoire.

Le pseudo-code qui fuit ressemble à ceci: xxx

Lorsque Func () termine et le destructeur est appelé, je vois que seul le destructeur du premier objet dans M_arr est appelé. Du débogueur, je vois que cela se fait de la suppression scalaire destructeurs et non du destructeur de suppression de vecteur. Cela explique pourquoi seul le premier objet est détruit. Ce que j'ai besoin de comprendre, c'est pourquoi la suppression scalaire est appelée le destructeur de la suppression de scalaire lorsque DELLEte [] est utilisé ???

J'ai trouvé ce fil - Pourquoi la suppression de vecteur est-elle appelée à la suite d'une suppression scalaire? . J'ai suivi les suggestions là-bas et nous sommes assurés que tous les modules soient compilés avec /md.

> Important de noter que lorsque la DLL contenant ClassFromdll était une bibliothèque statique et non une DLL, tout a fonctionné bien. La fuite n'a commencé que lorsque la bibliothèque statique a été modifiée pour être une DLL. Bien que le programme fuit en mode de sortie, il se bloque en mode de débogage sur Suppr [] M_arr. Le crash se produit dans dbgdel.cpp Line 52 - _block_type_is_valid (pHead-> nblockeuse).

sur des plates-formes UNIX Cette lib est également une libère partagée et que la suppression destructeurs de vecteur de vecteur est appelée et il n'y a pas de fuite. Le problème pourrait-il être avec le compilateur VC? Ou peut-être que d'autres paramètres des projets doivent être modifiés? J'utilise VC2003.

Merci d'avance!


7 commentaires

J'appellerais ce tableau. Habituellement par des gens de vecteur signifie std :: vecteur


Lorsque vous affirmez en mode de débogage si vous essayez de faire «Réessayer» après avoir attaché le débogueur où est-ce que le point de raccourci signifie-t-il? On dirait que vous avez une corruption en tas ici.


Cela peut ne pas être lié à votre problème, mais pourquoi utilisez-vous une telle version de compilateur?


@Naveen - Quand j'essaie de réessayer, rien ne se passe, tout se bloque tout jusqu'à ce que j'arrête le débogueur.


@Andrey - J'ai écrit destructeurs de la suppression du vecteur, car autant que je sache, c'est le nom de la fonction FUNC créée par le compilateur pour supprimer des tableaux.


@BlastFurnace - Je ne peux pas passer à un nouveau compilateur car cet EXE fait partie d'un gros produit, qui est développé sur VC2003 à ce stade.


La classeFromdll ferra-t-elle une suppression de son destructeur? Pourrait-il y avoir une confusion sur ce qui est supprimé?


5 Réponses :


0
votes

Je pense que c'est un cas clair d'alloué sur un tas et de la suppression d'un autre (rappelez-vous que la suppression [] doit interroger le tas pour le nombre d'éléments dans le tableau et si le tas ne contient même pas ce pointeur , il retournera "erreur" (pas vraiment) et on supposera que ce n'est qu'un élément et utilisez plutôt la suppression scalaire). Je pense que le problème que vous avez a été perdu en essayant de la modifier à un simple code. Je vous suggère de lire Cet article (c'est vieux, mais la technique de suppression est toujours très pertinente, j'utilise un Variation de cette technique moi-même et cela fonctionne comme un charme). Un moyen moderne de le faire consiste à joindre un pointeur de fonction Suppression à un pointeur intelligent (Shared_PTR) qui gère votre objet, de cette façon, en attribuant ce pointeur de fonction de suppression en même temps que vous créez l'objet dans une fonction d'usine, vous garantissez. que la suppression sera appelée sur le même tas que c'était alloué à partir de.


1 commentaires

Merci pour votre réponse. Je soupçonne aussi que cela peut être un problème avec différents tas de la DLL et de l'EXE, mais je ne vois tout simplement pas comment je peux entrer dans ce problème. Veuillez noter que les appels neufs et Supprimer sont fabriqués à partir de l'EXE. Il n'y a aucune usine utilisée dans le code actuel, il est très identique à ce que j'ai écrit ici. Il n'y a pas de surcharge de surcharge de l'opérateur de nouveau et de suppression. Tous les projets sont compilés avec / MD. Toute suggestion sur la manière dont l'allocation et la destruction pouvaient être effectuées sur différents tas alloueront grandement.



0
votes

En général, je vous recommande d'utiliser un std :: vecteur au lieu de ClassFromdll *. Construisez-le en passant dans taille . La suppression sera alors automatique. Malheureusement, je n'ai pas beaucoup d'expérience avec Suppr [], parce que j'ai toujours laissé la bibliothèque standard le faire pour moi; -)


0 commentaires

0
votes

Engage sur le code, je supposerais que l'objet a été copié par la copie par défaut CTOR, qui conduit à un bug de suppression double. Ceci est un comportement indéfini. Il peut sembler fonctionner, mais se rompre en raison de changements apparemment non liés - tels que la commutation d'une LIB à une DLL.


0 commentaires

1
votes

Une classe dans une DLL est extrêmement délicate, sans grande aide de compilateurs. Consultez cette réponse pour plus de détails Pourquoi c'est problematic: Comment puis-je appeler une fonction d'une DLL C ++ qui accepte un paramètre de type StringStream de C #? .

Version courte: Si l'interface de la classe utilise tout code inliné, vous rencontrerez des problèmes potentiels exactement comme celle-ci. Tout objet modélisé (tel que std :: string ) inclus.

Je suppose que c'est pourquoi. Il est similaire au problème @mikael Persson suggère.


0 commentaires

4
votes

Ceci est un ancien problème dans VC ++ concernant les DLL et les tableaux d'objets. La cause est une optimisation incorrecte du compilateur comme expliqué par Microsoft.

http://support.microsoft.com/kb/121216/en-us

Mieux vaut utiliser les conteneurs STL qui n'ont pas le problème du fait de l'utilisation d'un allocator.


1 commentaires

Merci d'avoir fourni ce lien! Cela confirme que ceci est en effet un bug de compilateur.