Jetant C++ exceptions au-delà des limites de la DLL
J'ai lu différentes choses sur la façon dont il ne faut pas allouer de mémoire de tas dans une DLL et de libérer de l'extérieur de cette DLL. Mais qu'en jetant un objet d'exception qui est un juste un temporaire (comme la plupart des objets d'exception sont)? E. g.:
throw my_exception( args ); //temporary: no heap allocation
Lorsque l'objet de l'exception est capturé en dehors de la DLL, le destructeur de l'objet sera finalement exécuté et la non-mémoire dans la mémoire de l'objet sera remis en état. Est-ce que ça puisque ce n'est pas un segment de mémoire?
- L'exception que vous jeter n'est pas une exception vous de capture; une copie est faite le long du chemin. Cela dit, je ne sais pas où la copie réside ou comment sa détruit.
- Est-ce encore le cas lorsque l'exception est interceptée par référence? Avez-vous une source?
- Autant que je sache, C++ nécessite qu'une exception ont un public très accessible en terme de constructeur de copie, mais c'est à une mise en œuvre que de l'utiliser pour faire des copies. Il peut très bien être le même objet qui est pris.
- De N3225,
15.1 Throwing an exception
,3: A throw-expression initializes a temporary object...
,5: The memory for the exception object is allocated in an unspecified way...
@Paul:5: When the thrown object is a class object, the copy/move constructor and the destructor shall be accessible, even if the copy/move operation is elided
- De N3225,
15.3 Handling an exception
16: The object declared in an exception-declaration or, if the exception-declaration does not specify a name, a temporary (12.2) is copy-initialized (8.5) from the exception object...
17: ...When the handler declares a reference to a non-constant object, any changes to the referenced object are changes to the temporary object initialized when the throw-expression was executed and will have effect should that object be rethrown.
- théoriquement, il pourrait être possible d'utiliser la même copie, mais pratiquement l'objet cesse d'exister en tant que la pile est déroulée.
- Merci, c'est exactement ce que je me demandais.
Vous devez vous connecter pour publier un commentaire.
Jetant C++ exceptions au-delà des limites de la DLL n'est possible que lorsque tous les modules utilisent le même runtime C++, dans ce cas, ils partagent un tas. Mais cela peut être un fardeau de l'entretien, en particulier quand les bibliothèques de plusieurs fournisseurs sont impliqués, de sorte qu'il est découragé.
Si vous voulez erreur de manipulation qui est portable sur plusieurs compilateurs/versions de compilateur/paramètres du compilateur, soit utiliser des codes de retour ou d'OS d'exceptions (par exemple, SEH sur Windows)/
Cela dépend de comment que la mémoire a été allouée et si le mécanisme pour le faire ("l'exécution" ou "gestionnaire de mémoire") est partagé entre les DLL et les autres parties de l'application. E. g. un
throw new my_exception( args );
pourrait aussi être dans l'ordre selon les détails.Vous pourriez faire vos exception référence compté, de sorte qu'il est livré avec la valeur intrinsèque de la connaissance de la façon de détruire sa propre instance (et appartenant à la mémoire).
À l'aide de
IMalloc
(voir MSDN), par exemple, l'attribution et le placementnew
serait un autre moyen (appelOleInitialize
avant) ...En effet, l'allocation de mémoire est un problème en fonction de ce qui est utilisé. Par exemple le mélange lié statiquement CRT et liée de façon dynamique CRT dans les différentes parties d'une application permettra d'aborder les questions de la même façon, le mélange de débogage et de publication code. Le problème ici est que le code qui est censé libérer la mémoire utilise un autre "gestionnaire de mémoire". Mais si l'objet lancé sait à propos de sa propre destruction, il devrait être bon, depuis le dtor code résider dans la même unité de compilation comme celle de l'allocation.