Quelle est la différence entre la pratique :
ou :
Quand est-ce une bonne idée d’utiliser calloc sur malloc ou vice versa ?
Quelle est la différence entre la pratique :
ou :
Quand est-ce une bonne idée d’utiliser calloc sur malloc ou vice versa ?
zéro-initialise la mémoire tampon, tandis que
laisse la mémoire non initialisée.
EDIT :
Remise à zéro la mémoire peut prendre un peu de temps, alors vous voudrez probablement utiliser si cette performance est un problème. Si il est plus important d’initialiser la mémoire, utilisez
. Par exemple, peut vous faire économiser un appel à
.
Un moins connu différence est que, dans les systèmes d'exploitation avec optimiste de l'allocation de mémoire, comme Linux, le pointeur retourné par malloc
n'est pas étayée par l'utilisation de la mémoire jusqu'à ce que le programme fait la touche.
calloc
, en effet, toucher la mémoire (il écrit des zéros) et ainsi vous serez sûr que l'OS est la sauvegarde de la répartition réelle de la RAM (ou swap). C'est aussi pourquoi il est plus lent que malloc (pas seulement à zéro, le système d'exploitation doit également trouver une zone de mémoire par l'éventuelle permutation d'autres procédés)
Voir par exemple ce DONC, la question de la poursuite de la discussion sur le comportement de malloc
On a souvent négligé l'avantage d' calloc
(implémentations conformes aux) il vous aidera à vous protéger contre les vulnérabilités de type débordement d'entier. Comparer:
size_t count = get_int32(file);
struct foo *bar = malloc(count * sizeof *bar);
vs
size_t count = get_int32(file);
struct foo *bar = calloc(count, sizeof *bar);
Le premier pourrait entraîner une petite allocation et suivantes dépassements de la mémoire tampon, si count
est plus grand que SIZE_MAX/sizeof *bar
. Ce dernier échouera automatiquement dans ce cas comme un objet que les grands ne peuvent pas être créés.
Bien sûr, vous pourriez avoir à être à l'affût de la non-conforme implémentations qui ignorent tout simplement la possibilité de débordement... Si c'est un souci sur les plates-formes que vous ciblez, vous devrez faire un test manuel pour le débordement de toute façon.
La documentation fait l'calloc ressembler à malloc, qui n'a tout simplement zéro-initialiser la mémoire; ce n'est pas la principale différence! L'idée de calloc est à abstraite de copie sur écriture de la sémantique pour l'allocation de la mémoire. Lorsque vous allouez de la mémoire avec calloc il toutes les cartes à la même page physique qui est initialisé à zéro. Lorsque l'une des pages de la mémoire allouée est écrit dans une page physique est attribué. Ceci est souvent utilisé de faire de grandes tables de hachage, par exemple depuis les pièces de hachage qui sont vides ne sont pas soutenu par une mémoire supplémentaire (pages); ils sont heureux de point de le seul initialisé à zéro de la page, qui peut être partagée entre plusieurs processus.
Tout écrire à l'adresse virtuelle est mappé à une page, si la page est le zéro-page, une autre page physique est affecté, le zéro de la page est copiée là et le flux de contrôle est renvoyé au client processus. Cela fonctionne de la même manière que les fichiers mappés en mémoire, la mémoire virtuelle, etc. du travail.. il utilise la pagination.
Voici une optimisation de l'histoire sur le sujet: http://blogs.fau.de/hager/2007/05/08/benchmarking-fun-with-calloc-and-zero-pages/
Il n'y a pas de différence dans la taille du bloc de mémoire alloué. calloc
seulement remplit le bloc de mémoire physique de tous les zéro-bits motif. Dans la pratique, il est souvent supposé que les objets situés dans le bloc de mémoire alloué avec calloc
ont initilial valeur que s'ils ont été initialisés avec littérale 0
, c'est à dire les entiers doivent avoir valeur d' 0
, à virgule flottante variables - la valeur de 0.0
,- pointeurs approprié de pointeur null valeur, et ainsi de suite.
À partir de la pédant point de vue, calloc
(ainsi que memset(..., 0, ...)
) n'est garanti que pour initialiser correctement (avec des zéros) les objets de type unsigned char
. Tout le reste n'est pas garanti d'être correctement initialisé et peut contenir des dits piège de la représentation, ce qui provoque un comportement indéfini. En d'autres termes, pour tout type autre que unsigned char
susmentionnés tous les zéro-bits patterm pourrait représenter une valeur illégale, le piège de la représentation.
Plus tard, dans l'un des Rectificatifs Techniques de standard C99, le comportement a été définie pour tous les types d'entiers (ce qui est logique). I. e. officiellement, dans le courant du langage C, vous pouvez initialiser uniquement les types d'entiers avec calloc
(et memset(..., 0, ...)
). À l'aide d'initialiser autre chose dans le cas général, conduit à un comportement indéfini, du point de vue du langage C.
Dans la pratique, calloc
œuvres, comme nous le savons tous :), mais si vous voulez l'utiliser (vu ci-dessus) est à vous. Personnellement, je préfère l'éviter complètement, utiliser malloc
au lieu et à mes propres initialisation.
Enfin, un autre détail important est qu' calloc
est nécessaire pour calculer le dernier bloc de la taille de l'interne, en multipliant la taille de l'élément par le nombre d'éléments. Tout en faisant cela, calloc
devez regarder pour un possible dépassement de capacité arithmétique. Il en résultera d'échec d'allocation (pointeur null) si la taille de bloc demandée ne peut pas être correctement calculée. Pendant ce temps, votre malloc
version ne tente pas de le regarder pour le débordement. Il alloue une partie "imprévisible" de la quantité de mémoire en cas de débordement se produit.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.