Différences entre l’utilisation des fonctions realloc et free -> malloc

Pourquoi utiliser la fonction realloc () pour redimensionner un tableau alloué dynamicment plutôt que d’utiliser la fonction free () avant d’appeler à nouveau la fonction malloc () (avantages et inconvénients, avantages et inconvénients, etc.)? C’est pour la programmation en C, mais je ne trouve pas l’étiquette appropriée. Merci d’avance.

L’avantage est que realloc préservera le contenu de la mémoire. Avec free + malloc, vous devez réinitialiser les données du tableau.

Je sais que cette question est très ancienne (on y a répondu en 2009), mais j’espère que ma réponse aidera ceux qui cherchent et trouveront cette question (comme moi).

Bien que ce critère ne soit pas définitif car la gestion de la mémoire varie selon les systèmes, les résultats ont tendance à être relativement normalisés. Ces résultats devraient donc être utilisés comme points de référence (si vous connaissez un cas réel, veuillez le dire au préalable). moi). J’utilise Windows 7 sur un Intel Core i3 2310M QuadCore à 2,10 GHz avec 4 Go de RAM. Pas le meilleur matériel de tous les temps, mais le meilleur que j’ai actuellement.

Ce sharepoint référence fait qu’il commence avec une certaine quantité de mémoire (INITIAL_MEMORY) et réalloue de manière répétée par petites quantités (BYTE_STEP) jusqu’à ce qu’il alloue / libère complètement ALLOCATE_MEMORY. Pour cela, il tente 6 approches:

  1. Augmenter les pertes de Malloc: free () et malloc () plus de mémoire.
  2. Réduction des pertes Malloc: free () et malloc () moins de mémoire.
  3. Augmenter Malloc: malloc () plus de mémoire, copier des données et libérer de la mémoire précédente.
  4. Décroissant Malloc: malloc () moins de mémoire, copie des données et libère de la mémoire précédente.
  5. Augmenter Realloc: realloc () plus de mémoire.
  6. Réduction de Realloc: realloc () moins de mémoire.

Donc, premier test: Commencez avec 2 Mo et allouez ± 1 Mo en étapes de 1 Ko:

Increasing Lossful Malloc took 3 ms Decreasing Lossful Malloc took 5 ms Increasing Malloc took 1 265 ms Decreasing Malloc took 744 ms Increasing Realloc took 316 ms Decreasing Realloc took 0 ms 

Comme nous pouvons le constater, la copie manuelle avec memcpy est toujours plus lente que realloc, car dans ce scénario, malloc est assuré d’allouer une nouvelle mémoire et vous êtes obligé de copier les données dans chaque allocation, ce qui nous montre que realloc utilise effectivement la même adresse. et en augmentant la taille du bloc dans certains cas. Donc si vous voulez conserver vos données, realloc est probablement ce que vous voulez utiliser. Afin de simplifier les choses, je ne continuerai pas à tester cette approche malloc sans perte.

Passons au test suivant: mémoire initiale de 32 Mo, allocation de 16 Mo en étapes de 16 Ko:

 Increasing Lossful Malloc took 4 ms Decreasing Lossful Malloc took 4 ms Increasing Realloc took 21 453 ms Decreasing Realloc took 0 ms 

Nous pouvons maintenant constater que l’augmentation de realloc prend beaucoup de temps par rapport aux autres tests. Le realloc décroissant n’a même pas atteint 1 ms. Cela montre que si vous ne voulez pas garder votre mémoire, vous devriez utiliser une approche free-> malloc, ou le fait-elle? Regardez ces résultats:

 Increasing Lossful Malloc took 777 ms Decreasing Lossful Malloc took 729 ms Decreasing Realloc took 19 ms 

(Ces résultats étaient trop proches, j’ai donc effectué plusieurs tests et les ai moyennés.)

Réduire définitivement la taille de la mémoire est plus efficace avec realloc (). C’est probablement parce que realloc n’a pas besoin de rechercher un nouveau bloc de mémoire, il utilise simplement le précédent et le réduit. C’est une grosse différence de performance si vous utilisez beaucoup l’allocation.

En outre, nous pouvons voir que le malloc croissant est légèrement plus lent que le décroissant, même lorsque les deux font fondamentalement la même chose: trouver un bloc de mémoire et l’allouer. Cette différence est probablement due au fait que lors de la recherche de blocs plus importants, malloc doit rechercher une moyenne plus longue que lors de la recherche de blocs plus petits. Par exemple, s’il existe un bloc de 30 Mo, un malloc allouant 16 Mo l’utilisera, mais un malloc allouant 32 Mo devra l’ignorer et poursuivre la recherche et l’utilisation du temps imparti. C’est probablement pourquoi les résultats ont tellement varié lors de mes tests.

En conclusion / TLDR:

  1. Si vous devez conserver vos données, utilisez realloc (). C’est environ 4 fois plus rapide que d’utiliser malloc () / free () et de copier vos données lors de la mise à l’échelle . Lors de la réduction , il est 10 000 à 100 000 fois plus rapide. NE JAMAIS copier des choses manuellement.
  2. Si vous n’avez pas besoin de conserver vos données, vous devez utiliser malloc () / free () pour augmenter (augmenter la taille de la mémoire) mais avec realloc () lors de la réduction (réduction de la taille de la mémoire).
  3. Si vous ne connaissez pas la taille précédente (vous ne savez pas si vous réduisez ou augmentez), utilisez malloc () / free (). Lors de la réduction, realloc () est environ 40 fois plus rapide, mais lors de la réduction, realloc () est environ 7600 fois plus lente . Sauf si votre programme effectue quelques allocations énormes et des tonnes de petites désallocations (environ 200 fois plus de désallocations que d’allocations, ce qui est possible ), vous devez utiliser malloc () / free ().

Voici ma source de référence: test.cpp

Maintenant, s’il vous plaît, si j’ai fait quelque chose de mal ou si vous avez des commentaires, n’hésitez pas à me dire / à me corriger.

Realloc peut changer la taille du bloc en place, ou en allouer un nouveau et en copier autant que nécessaire. En revanche, malloc et free ensemble ne peuvent en allouer qu’un nouveau et vous devez faire votre propre copie.

Pour être franc, realloc n’est pas beaucoup utilisé de nos jours car il ne fonctionne pas bien avec C ++. En conséquence, les gestionnaires de mémoire ont tendance à ne pas optimiser leurs performances.

J’avais un programme qui faisait beaucoup d’appels free () et malloc () pour créer un tableau dynamic, et je pensais optimiser en réutilisant le tableau existant lorsque cela était possible. Les tests ont montré que realloc () est en moyenne plus lent que d’appeler free () et malloc (). Je suppose que cela a du sens, car parfois, il pousserait, et exigerait peut-être une copie.

“plutôt que d’utiliser la fonction free () avant d’appeler à nouveau la fonction malloc ()”

Si vous libérez le tableau existant, vous avez perdu tout son contenu, vous ne pouvez donc pas “agrandir” le tableau dans le sens habituel.