Différence entre les malloc et calloc?
Quelle est la différence entre faire:
ptr = (char **) malloc (MAXELEMS * sizeof(char *));
ou:
ptr = (char **) calloc (MAXELEMS, sizeof(char*));
Quand est-ce une bonne idée d'utiliser calloc plus de malloc ou vice-versa?
- En C, vous ne lancez pas le résultat de
malloc
famille - En C, vous pouvez écrire le ci-dessus de manière plus générale comme:
ptr = calloc(MAXELEMS, sizeof(*ptr));
- Un post intéressant sur la différence entre calloc et le malloc+memset vorpus.org/blog/why-does-calloc-exist
- Moi aussi, je trouve que le blog, après je n'était pas satisfait avec tant de réponses sur le net. Nathaniel J. Smith mérite+ de 100 points pour son analyse.
- Connexes: Peut calloc() allouer plus de SIZE_MAX au total?
Vous devez vous connecter pour publier un commentaire.
calloc()
zéro-initialise la mémoire tampon, tandis quemalloc()
feuilles de la mémoire non initialisée.EDIT:
Réinitialisation de la mémoire peut prendre un peu de temps, alors vous voudrez probablement utiliser
malloc()
si la performance est un problème. Si l'initialisation de la mémoire est de plus en plus important, l'utilisationcalloc()
. Par exemple,calloc()
peut vous faire gagner un appel àmemset()
.calloc
n'est pas nécessairement plus cher, puisque l'OS peut faire quelques trucs pour l'accélérer. Je sais que FreeBSD, quand il fait tout d'inactivité du PROCESSEUR temps, l'utilise pour exécuter un processus simple qui tourne et remet à zéro libéré des blocs de mémoire, et les marques de blocs ainsi les processus avec un drapeau. Ainsi, lorsque vous vouscalloc
, il tente d'abord de trouver l'un de ces pré-mise à zéro des blocs et simplement le donner à vous - et plus il a de chance de trouver un.float
(et d'autres types pour lesquels tous les bits 0 ne peut pas dire ce que vous pensez qu'ils signifient).malloc
parfois à l'aide demmap
pour chaque allocation avec une page de garde à droite après la dernière alloués octet, et je pourrais intégrer votre idée pour le remplissage de la mémoire avec un crash induisant la valeur du pointeur de trop.calloc - allocate and clear memory block
minnie.tuhs.org/cgi-bin/utree.pl?file=V7M/src/libc/gen/calloc.c à Partir de JimBalter commentaire ici stackoverflow.com/a/12555996/50979calloc()
peut raisonnablement supposer être initialisé à laNULL
pointeur.calloc
etmalloc
sont contigus dans la nature. J'ai lu ici qui -The only difference between malloc() and calloc() is that, malloc() allocates single block of memory whereas calloc() allocates multiple blocks of memory each of same size and sets all bytes to zero.
je crois que c'est incorrect. N'est-ce pas? Je croiscalloc
a obtenu son nom declear allocated memory
c'est à dire zéro de la mémoire allouée, qui est la seule différence quand je le compare àmalloc
.memset(..)
" Ce qui serait intéressant, c'est, lequel est le plus rapide 1.malloc(..)
&memset(..)
, oucalloc(..)
.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, l'OS doit également trouver une zone de mémoire par éventuellement échanger des autres processus)Voir, par exemple, cette SORTE de question pour la poursuite de la discussion sur le comportement de la fonction malloc
calloc
n'a pas besoin d'écrire des zéros. Si le bloc alloué se compose essentiellement de nouveau à zéro des pages fournies par le système d'exploitation, il peut laisser intacte. Bien sûr, cela nécessitecalloc
à être à l'écoute pour le système d'exploitation plutôt que d'une bibliothèque générique de la fonction sur le dessus demalloc
. Ou, un réalisateur pourrait fairecalloc
comparer chaque mot contre zéro avant la mise à zéro il. Ce ne serait pas sauver tout le temps, mais il permettrait d'éviter de salir les nouvelles pages.dlmalloc
-comme les implémentations de sauter lememset
si le morceau a été obtenu parmmap
ing nouveau les pages anonymes (ou l'équivalent). Généralement ce type de répartition est utilisée pour les plus grands morceaux, en commençant à 256k ou donc. Je ne sais pas du tout implémentations qui ne la comparaison par rapport à zéro avant d'écrire de zéro en dehors de mon propre.omalloc
aussi saute lememset
;calloc
n'a pas besoin de toucher à toutes les pages qui ne sont pas déjà utilisés par l'application (le cache de la page), jamais. Cependant, extrêmement primitifcalloc
implémentations différent.VirtualAlloc
alloue également de pré-mise à zéro de la mémoire.Un souvent négligé, l'avantage de
calloc
est que (des implémentations conformes aux) il vous aidera à vous protéger contre les vulnérabilités de type débordement d'entier. Comparer:vs
L'ancien pourrait entraîner une petite allocation et suivantes dépassements de la mémoire tampon, si
count
est plus grand queSIZE_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.
char
est pas un dépassement de capacité, mais plutôt une mise en œuvre conversion définie lors de l'affectation du résultat dans unchar
objet.size_t
parce que je ne vois pas de problème quandsize_t
est de 64 bits de large.size_t
il aurait été évident. Certes, c'est mon problème que je développe maintenant uniquement sur 64 bits des machines, mais l'évidence n'est pas nécessairement le même que d'autres (par exemple, je suis vraiment bon à trouver desint
débordements dans le code de gens avec un 32 bits modèle mental).size_t
est en 64 bits, donc c'est pas un problème", c'est une façon erronée de penser qui va conduire à des bugs de sécurité.size_t
est un type abstrait qui représente tailles, et il n'y a aucune raison de penser que l'arbitraire du produit d'un nombre de 32 bits et unsize_t
(note:sizeof *bar
pourrait, en principe, être supérieur à 2^32 sur 64 bits C mise en œuvre!) s'inscrit danssize_t
.size_t
, sisize_t
est de 16 Bits (ou toute valeur entre) vous auriez également un problème (ce qui est fréquent sur les Microcontrôleurs qui ont souvent moins de 64KiB espace total).De la documentation rend la 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é aveccalloc
ont initilial valeur que s'ils ont été initialisés avec littérale0
, c'est à dire les entiers doivent avoir une valeur de0
, virgule flottante variables - la valeur de0.0
, les pointeurs, - la bonne de pointeur null valeur, et ainsi de suite.De la pédant point de vue cependant,
calloc
(ainsi quememset(..., 0, ...)
) n'est garanti que pour initialiser correctement (avec des zéros) les objets de typeunsigned 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 queunsigned char
ladite 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
(etmemset(..., 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, utilisermalloc
place et faire de mon propre initialisation.Enfin, un autre détail important est que
calloc
est nécessaire pour calculer le dernier bloc de la taille de en 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, votremalloc
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.memset(p, v, n * sizeof type);
un problème parce quen * sizeof type
peut déborder. Suppose que je vais avoir besoin d'utiliser unfor(i=0;i<n;i++) p[i]=v;
boucle robuste code.n
éléments existent, où un élément de la taillesizeof type
, puisn*sizeof type
ne peut pas déborder, parce que la taille maximale d'un objet doit être inférieure àSIZE_MAX
.SIZE_MAX
, mais il n'y a pas les tableaux ici. Le pointeur retourné à partir decalloc()
peut pointer vers la mémoire allouée que dépasseSIZE_MAX
. De nombreuses implémentations ne limite le produit des 2 arguments pourcalloc()
àSIZE_MAX
, mais la C spec ne pas imposer cette limite.d'un article L'analyse comparative du plaisir avec calloc() et zéro pages sur Georg Hager Blog
calloc
est généralementmalloc+memset
à 0Il est généralement un peu mieux utiliser
malloc+memset
explicitement, en particulier lorsque vous faites quelque chose comme:C'est mieux parce que
sizeof(Item)
est savoir pour le compilateur au moment de la compilation et le compilateur dans la plupart des cas, le remplacer avec le meilleur des instructions à zéro de la mémoire. D'autre part, simemset
qui se passe danscalloc
, le paramètre de taille de l'allocation n'est pas compilé dans lecalloc
code et réelmemset
est souvent appelé, qui pourrait contenir le code-octet par octet de remplissage jusqu'long de la frontière, que le cycle de remplissage de la mémoire danssizeof(long)
morceaux et enfin, octet par octet, remplir l'espace restant. Même si l'allocation est assez intelligent pour appeler quelques -aligned_memset
il sera toujours un générique en boucle.Une exception notable lorsque vous faites malloc/calloc d'une très grande partie de la mémoire (certains power_of_two kilo-octets), auquel cas l'allocation peut être fait directement à partir du noyau. Comme OS de noyaux généralement à zéro, toute la mémoire qu'ils donnent à l'écart pour des raisons de sécurité, assez intelligent calloc pourrait juste retourner supplémentaires sans réduction à zéro. Encore une fois - si vous êtes juste de l'allocation de quelque chose que vous savez est petite, vous pourriez être mieux avec malloc+memset de performance.
calloc()
plus lent quemalloc()
: la multiplication de la taille.calloc()
est nécessaire pour utiliser un générique de multiplication (sisize_t
est de 64 bits, même le très coûteux 64 bits*64 bits=64 bits opération), tandis que la fonction malloc() auront souvent une compilation constante de temps.struct foo { char a,b,c; };
.calloc
est toujours mieux quemalloc
+memset
, si vous allez toujours à effacer toutemalloc
ed région.calloc
a une prudente mais efficace de vérifier int dépassement au niveau de la taille * éléments de, trop.Différence 1:
malloc()
généralement alloue le bloc de mémoire et il est initialisé segment de mémoire.calloc()
alloue le bloc de mémoire et d'initialiser tous les bloc de mémoire à 0.Différence 2:
Si vous considérez
malloc()
syntaxe, il faudra seulement 1 argument. Considérons l'exemple suivant ci-dessous:Ex: Si vous souhaitez allouer 10 bloc de mémoire pour le type int,
Si vous considérez
calloc()
syntaxe, il faudra 2 arguments. Considérons l'exemple suivant ci-dessous:Ex: si vous souhaitez allouer 10 blocs de mémoire de type int et Initialiser tous à ZÉRO,
Similitude:
Les deux
malloc()
etcalloc()
sera de retour void* par défaut si elles ne sont pas de type coulé .!Il y a deux différences.
Tout d'abord, est le nombre d'arguments.
malloc()
prend un seul argument (de mémoire, en octets), alors quecalloc()
a besoin de deux arguments.Deuxièmement,
malloc()
ne pas initialiser la mémoire allouée, alors quecalloc()
initialise la mémoire allouée à ZÉRO.calloc()
alloue une zone mémoire, la longueur sera le produit de ses paramètres.calloc
remplit la mémoire à ZÉRO et retourne un pointeur vers le premier octet. Si elle ne parvient pas à trouver assez d'espace, il renvoie uneNULL
pointeur.Syntaxe:
ptr_var=(cast_type *)calloc(no_of_blocks , size_of_each_block);
c'est à dire
ptr_var=(type *)calloc(n,s);
malloc()
alloue un bloc de mémoire de REQUSTED TAILLE et retourne un pointeur vers le premier octet. Si elle ne parvient pas à trouver requsted quantité de mémoire il retourne un pointeur null.Syntaxe:
ptr_var=(cast_type *)malloc(Size_in_bytes);
Le
malloc()
prise de fonction à un argument, qui est le nombre d'octets à allouer, tandis que lecalloc()
fonction prend deux arguments, l'un étant le nombre d'éléments, et l'autre étant le nombre d'octets à allouer pour chacun de ces éléments. Aussi,calloc()
initialise l'espace alloué pour les zéros, alors quemalloc()
ne pas.La
calloc()
fonction qui est déclarée dans le<stdlib.h>
en-tête offre quelques avantages par rapport à lamalloc()
fonction.zéro.
Une différence pas encore parlé: limite de taille
void *malloc(size_t size)
ne peut allouer jusqu'àSIZE_MAX
.void *calloc(size_t nmemb, size_t size);
peut allouer environSIZE_MAX*SIZE_MAX
.Cette capacité n'est pas souvent utilisé dans de nombreuses plates-formes avec adressage linéaire. De tels systèmes limite
calloc()
avecnmemb * size <= SIZE_MAX
.Envisager un type de 512 octets appelé
disk_sector
et le code veut utiliser beaucoup de secteurs. Ici, le code ne peut utiliser jusqu'àSIZE_MAX/sizeof disk_sector
secteurs.De considérer les éléments suivants qui permet une plus grande allocation.
Maintenant, si un tel système peut fournir un tel grand répartition est une autre affaire. La plupart aujourd'hui ne le sera pas. Pourtant, il y a eu pendant de nombreuses années lorsque
SIZE_MAX
a 65535. Compte tenu de La loi de Moore, pensez que cela va se produire à propos de 2030, avec certains modèles de mémoire avecSIZE_MAX == 4294967295
et des pools de mémoire dans le 100 de Go.size_t
de plus de 32 bits. La seule question est de savoir si l'aidecalloc
avec les valeurs dont le produit est supérieure àSIZE_MAX
pourrait être invoqué pour un rendement de zéro plutôt que de retourner un pointeur vers une petite allocation.calloc()
allocations dépassantSIZE_MAX
. Il est arrivé dans le passé avec 16 bitssize_t
et que la mémoire continue à les rabaisser, je ne vois pas pourquoi il ne peut pas se passer d'aller de l'avant, même si c'est pas commune.SIZE_MAX
. Il n'est certainement pas exiger toute circonstance où une telle répartition peut réussir; je ne suis pas sûr qu'il y a tout avantage particulier de rendre obligatoire que les implémentations qui ne peut pas gérer ces allocations doivent retournerNULL
(en particulier étant donné que c'est commun pour certaines implémentations d'avoirmalloc
renvoient des pointeurs à l'espace qui n'est pas encore engagé et peuvent ne pas être disponibles lorsque le code réellement essaie de l'utiliser).calloc
fonction retourne un pointeur null ou un pointeur vers l'espace alloué." Il ne dispense pas de maths de dépassement denmemb * size > SIZE_MAX
.calloc()
qui retourne une des pointeurs vers la mémoire >SIZE_MAX (4G-1)
.size_t
àuint64_t
?malloc()
etcalloc()
sont des fonctions de la bibliothèque C standard qui permettent d'allocation dynamique de la mémoire, en ce sens qu'ils permettent à la fois de l'allocation de mémoire en cours d'exécution.Leurs prototypes sont comme suit:
Il y a principalement deux différences entre les deux:
Comportement:
malloc()
alloue un bloc de mémoire, sans l'initialiser, et la lecture de contenu à partir de ce bloc de résultat dans les ordures valeurs.calloc()
, d'autre part, alloue un bloc de mémoire et l'initialise à zéros, et, évidemment, en lisant le contenu de ce bloc va entraîner des zéros.Syntaxe:
malloc()
prend 1 argument (de la taille à allouer), etcalloc()
prend deux arguments (nombre de blocs alloués et la taille de chaque bloc).La valeur de retour de deux est un pointeur vers le bloc alloué de la mémoire, en cas de succès. Sinon, NULL sera renvoyé indiquant l'échec d'allocation de mémoire.
Exemple:
Les mêmes fonctionnalités que
calloc()
peut être réalisé en utilisantmalloc()
etmemset()
:Noter que
malloc()
est utilisé de préférence surcalloc()
car c'est plus rapide. Si l'initialisation à zéro des valeurs est voulu, utilisezcalloc()
à la place.Pas de blocs:
malloc() Affecte seul bloc de demandé de mémoire,
calloc() Affecte plusieurs blocs de la mémoire demandée
Initialisation:
malloc() n'est pas claire et initialiser la mémoire allouée.
calloc() initialiser la mémoire allouée par zéro.
Vitesse:
malloc() la vitesse est Rapide.
calloc() la vitesse est Relativement lente.
Syntex:
Argument:
Si vous envisagez de malloc() de la syntaxe, il faudra seulement 1 argument.
Si vous envisagez de calloc() de la syntaxe, il faudra 2 arguments.
Manière de l'Allocation de mémoire::
malloc() fonction alloue de la mémoire, de la "taille" à partir de la tas.
calloc() fonction alloue de la mémoire qui est la taille de ce qui est égal à ‘num *taille".
Sens sur le nom:
Le nom de la fonction malloc moyens attribués à l'allocation de la mémoire.
Le nom de calloc signifie allocation contiguë.