Allocation de mémoire entre la liaison statique et dynamic du runtime C

L’architecture de mon programme implique des plugins (dll) et l’exe (évidemment). Nous sums le seul fournisseur de plugins. On m’a dit qu’allouer de la mémoire dans un plugin puis le libérer dans le code exe constituait un problème potentiel si nous lions statiquement le runtime c. Cependant, si nous l’associons de manière dynamic, il n’y avait qu’un seul tas et le runtime c avait access à tout cela. Nous sums passés à la liaison dynamic sur la base de ce conseil, mais tout ce que nous avons vu depuis le commutateur est des maux de tête et des problèmes liés à la dissortingbution et à l’installation des nouvelles exécutions. (Je ne sais pas ce que nous avons évité en termes de problèmes d’allocation de mémoire.)

Quelles sont les implications de l’allocation de mémoire? Dites qu’un plugin alloue de la mémoire et que l’exe la libère. Existe-t-il un comportement différent entre le runtime c lié statiquement et dynamicment? Aurons-nous du mal à lier statiquement le runtime C si nous utilisons des plugins? Si nous revenons à la liaison statique, cela va-t-il gâcher la détection des memory leaks et la génération de rapports de vidage sur incident?

Est-ce que certaines questions soulevées par les commentaires sur la version d’exécution de VC ++ que je choisis sont statiques ou dynamics? spécifiquement quelle version d’exécution de VC ++ est-ce que je choisis – statique ou dynamic?

Des discussions sont également disponibles sur http://msdn.microsoft.com/en-us/library/abx4dbyh(v=VS.100).aspx .

Si vous souhaitez allouer du tas dans un module et libérer dans un autre, vous devez simplement lier dynamicment le moteur d’exécution. De plus, toutes les parties doivent lier dynamicment le même runtime. Une fois que vous faites cela, il n’y aura plus de problèmes.

Maintenant, c’est une contrainte assez sévère à imposer à vos plugins et vous devriez réfléchir à deux fois avant de le faire. Forcer tous les auteurs de plug-in à mettre à niveau avec vous est une lourde tâche. Je vous recommanderais d’envisager de refactoriser votre interface afin que les allocations soient toujours associées à des désallocations au sein d’un même module. Cela soulève les contraintes que je décris ci-dessus et facilite la vie de vos auteurs de plug-in.

Pour ce qui est des raisons pour lesquelles vous continuez à avoir des erreurs d’exécution, c’est difficile à dire. Je suppose que tous les modules ne sont pas liés à la même version du moteur d’exécution.


Dans les commentaires, vous indiquez que vous contrôlez tous les plugins. Cela signifie que les contraintes dont je viens de parler ne constituent pas une imposition, car il est facile d’utiliser la même version du compilateur pour tous les modules. Toutefois, les règles relatives à la liaison dynamic avec l’access au tas entre modules demeurent. Vous devez utiliser la liaison dynamic avec la même version du moteur d’exécution.

Les fonctions pour allouer / libérer de la mémoire sont appariées; vous ne pouvez pas appeler my_malloc () puis utiliser free (), ni appeler le “nouvel” opérateur de C ++, puis appeler FreeMem () depuis une bibliothèque aléatoire 🙂

Votre plugin a besoin d’une méthode bien connue d’allocation et de libération de mémoire. Si cela se fait avec malloc (), alors votre programme principal peut probablement juste faire free () Mais s’il fait quelque chose de plus exotique (Windows a des tonnes d’allocateurs de mémoire disponibles), votre API de plug-in doit permettre à l’exe principal d’appeler le plug-in pour libérer ses données.

Donc, si votre programme principal appelle

foo = plugin->allocate_something() 

alors il serait sage pour votre API de plugin d’avoir un correspondant

 plugin->free_something (foo) 

que le programme principal peut utiliser sans ambiguïté.

De toute évidence, le problème est que le plug-in et l’application principale utilisent des gestionnaires de tas différents et incompatibles qui obstruent les structures de données de chacun. L’utilisation d’un tube cathodique dynamic oblige théoriquement les deux à utiliser le même tube cathodique et sont donc automatiquement compatibles.

Dans le cas général, il peut être préférable de confier au plug-in la responsabilité d’allouer et de supprimer toute la mémoire utilisée. Cela implique éventuellement l’ajout d’API au plug-in pour supprimer les objects créés précédemment et retransmis à l’application principale. Cela fournit également une bonne isolation entre le plug-in et l’application, permettant au plug-in d’utiliser des allocateurs spécialisés pour des performances ou pour d’autres raisons. C’est ce que fait COM, par exemple.