Quelle est la différence entre malloc () et HeapAlloc ()? Autant que je sache, malloc alloue de la mémoire à partir du tas, tout comme HeapAlloc, non?
Alors, quelle est la difference?
Merci!
Vous avez raison, ils allouent tous deux de la mémoire à partir d'un tas. Mais il y a des différences:
malloc()
est portable, fait partie de la norme.HeapAlloc()
n'est pas portable, c'est une fonction API Windows.Il est fort possible que, sous Windows, malloc
soit implémenté au-dessus de HeapAlloc
. Je m'attendrais à ce que malloc
soit plus rapide que HeapAlloc
.
HeapAlloc
a plus de flexibilité que malloc
. En particulier, il vous permet de spécifier le segment à partir duquel vous souhaitez allouer. Cela s'adresse à plusieurs tas par processus.
Pour presque tous les scénarios de codage, vous utiliseriez malloc
au lieu de HeapAlloc
. Bien que puisque vous ayez tagué votre question C++, je m'attendrais à ce que vous utilisiez new
!
En fait, malloc () (et d’autres fonctions de tas C d’exécution) dépendent du module, ce qui signifie que si vous appelez malloc () dans le code d’un module (c’est-à-dire une DLL), vous devez appeler free () dans le code du même module. ou vous pourriez souffrir de la corruption du tas (et cela a été bien documenté). L'utilisation de HeapAlloc () avec GetProcessHeap () à la place de malloc (), y compris la surcharge des opérateurs nouveaux et delete, permet de faire passer des objets alloués dynamiquement entre les modules sans avoir à s'inquiéter de la corruption de la mémoire un module et libéré dans le code d'un autre module une fois que le pointeur sur un bloc de mémoire a été transmis à un module externe.
Avec Visual C++, la fonction malloc()
ou l'opérateur new
appelle finalement HeapAlloc()
. Si vous déboguez le code, vous constaterez que la fonction _heap_alloc_base()
(dans le fichier malloc.c
) appelle return HeapAlloc(_crtheap, 0, size)
, où _crtheap
est un segment de mémoire global créé avec HeapCreate()
.
La fonction HeapAlloc()
permet de minimiser le temps système de la mémoire, avec un temps système minimal de 8 octets par allocation. Le plus grand que j'ai vu est de 15 octets par allocation, pour des allocations allant de 1 octet à 100 000 octets. Les plus gros blocs ont des frais généraux plus importants, mais en tant que pourcentage du total alloué, ils restent inférieurs à 2,5% de la charge utile.
Je ne peux pas commenter les performances car je n'ai pas comparé la fonction HeapAlloc()
à une routine personnalisée. Toutefois, en ce qui concerne la surcharge de mémoire liée à l'utilisation de HeapAlloc()
, celle-ci est incroyablement basse.
malloc
est une fonction de la bibliothèque standard C (et également de la bibliothèque standard C++).
HeapAlloc
est une fonction de l'API Windows.
Ce dernier vous permet de spécifier le tas à allouer, ce qui, à mon avis, peut être utile pour éviter la sérialisation des demandes d'allocation dans différents threads (notez l'indicateur HEAP_NO_SERIALIZE
).
Vive & hth.,
De plus, vous pouvez vous référer à:
https://msdn.Microsoft.com/en-us/library/windows/desktop/aa366705(v=vs.85).aspx
Cela signifie que vous pouvez activer certaines fonctionnalités du HEAP gérées par l'allocateur de mémoire WinApi, par exemple "HeapEnableTerminationOnCorruption".
Si je comprends bien, certaines protections de base contre le débordement de tas peuvent être considérées comme une valeur ajoutée à votre application en termes de sécurité.
(par exemple, je préférerais crasher mon application (en tant que propriétaire de l'application) plutôt que d'exécuter du code arbitraire)
Une autre chose est que cela pourrait être utile au début de la phase de développement, afin que vous puissiez résoudre les problèmes de mémoire avant de passer à la production.
Dans les systèmes où plusieurs DLL peuvent aller et venir (via LoadLibrary/Freelibrary), et quand la mémoire peut être allouée dans une DLL, mais libérée dans une autre (voir la réponse précédente), HeapAlloc et les fonctions associées semblent être le dénominateur commun le plus bas. partage de mémoire réussi.
Thread safe, probablement très optimisé par de nombreux doctorants, HeapAlloc semble fonctionner dans toutes sortes de situations où notre code moins partageable utilisant malloc/free échouerait.
Nous sommes une boutique intégrée C++. Nous avons donc surchargé les opérations de suppression/suppression d'opérateurs sur l'ensemble de notre système pour utiliser HeapAlloc (GetProcessHeap ()), qui peut être modifié (sur la cible) ou natif (sur Windows) pour la portabilité du code.
Jusqu'à présent, aucun problème maintenant que nous avons contourné malloc/free qui semble indiscutablement DLL spécifiquement, un nouveau "tas" pour chaque charge DLL.
malloc est exporté fonction par la bibliothèque d'exécution C (CRT) spécifique au compilateur.
C Le nom de la DLL d'exécution de la bibliothèque d'exécution passe des versions de Visual Studio aux versions .
HeapAlloc la fonction est exportée par kernel32.dll présent dans le dossier Windows.
C’est ce que MS dit à ce sujet: http://msdn.Microsoft.com/en-us/library/windows/desktop/aa366533(v=vs.85).aspx
Une chose dont on a parlé jusqu’à présent est la suivante: "La fonction malloc a le désavantage d’être dépendante de l’exécution. Le nouvel opérateur a l’inconvénient d’être dépendante du compilateur et de la langue."
En outre, "il peut être demandé à HeapAlloc de déclencher une exception si la mémoire ne peut pas être allouée"
Donc, si vous voulez que votre programme fonctionne avec n'importe quel tube cathodique, ou peut-être aucun tube cathodique, utilisez HeapAlloc. Peut-être que seules les personnes qui feraient une telle chose seraient des auteurs de logiciels malveillants. Si vous écrivez une application nécessitant beaucoup de mémoire avec des modèles d’allocation/utilisation de mémoire spécifiques, vous pouvez également utiliser votre propre allocateur de tas au lieu d’utiliser un système CRT.