Différence entre malloc et calloc?

780

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 sur malloc ou vice versa?

user105033
la source
8
En C, vous pouvez écrire ce qui précède de manière plus générique:ptr = calloc(MAXELEMS, sizeof(*ptr));
chqrlie
7
Un article intéressant sur la différence entre calloc et malloc + memset vorpus.org/blog/why-does-calloc-exist
ddddavidee
2
@ddddavidee Moi aussi, j'ai trouvé ce blog après que j'étais insatisfait de tant de réponses sur le net. Nathaniel J. Smith mérite plus de 100 points SO pour son analyse.
lifebalance

Réponses:

851

calloc()vous donne un tampon zéro initialisé, tout en malloc()laissant la mémoire non initialisée.

Pour les allocations importantes, la plupart des callocimplémentations sous les OS traditionnels obtiendront des pages à zéro connu de l'OS (par exemple via POSIX mmap(MAP_ANONYMOUS)ou Windows VirtualAlloc), il n'a donc pas besoin de les écrire dans l'espace utilisateur. C'est ainsi que la normale mallocobtient plus de pages du système d'exploitation; callocprofite simplement de la garantie de l'OS.

Cela signifie que la callocmémoire peut toujours être «propre» et allouée paresseusement, et la copie sur écriture mappée sur une page physique partagée de zéros à l'échelle du système. (En supposant un système avec mémoire virtuelle.)

Certains compilateurs peuvent même optimiser malloc + memset (0) en calloc pour vous, mais vous devez utiliser explicitement calloc si vous voulez que la mémoire soit lue 0.

Si vous ne lirez jamais la mémoire avant de l'écrire, utilisez-la mallocafin qu'elle puisse (potentiellement) vous donner de la mémoire sale à partir de sa liste libre interne au lieu d'obtenir de nouvelles pages du système d'exploitation. (Ou au lieu de mettre à zéro un bloc de mémoire sur la liste gratuite pour une petite allocation).


Les implémentations intégrées de callocpeuvent laisser à calloclui-même la mémoire zéro s'il n'y a pas de système d'exploitation, ou ce n'est pas un système d'exploitation multi-utilisateurs sophistiqué qui met à zéro les pages pour arrêter les fuites d'informations entre les processus.

Sur Linux embarqué, malloc pourrait mmap(MAP_UNINITIALIZED|MAP_ANONYMOUS), qui n'est activé que pour certains noyaux intégrés car il n'est pas sécurisé sur un système multi-utilisateur.

Fred Larson
la source
224
Les variantes * alloc sont assez mnémoniques - clear-alloc, memory-alloc, re-alloc.
Cascabel
43
Utilisez malloc () si vous allez définir tout ce que vous utilisez dans l'espace alloué. Utilisez calloc () si vous voulez laisser des parties des données non initialisées - et il serait avantageux de mettre à zéro les parties non définies.
Jonathan Leffler
268
callocn'est pas nécessairement plus cher, car OS peut faire quelques trucs pour l'accélérer. Je sais que FreeBSD, quand il obtient un temps processeur inactif, l'utilise pour exécuter un processus simple qui fait le tour et met à zéro les blocs de mémoire désalloués, et marque les blocs ainsi traités avec un indicateur. Ainsi, lorsque vous le faites calloc, il essaie d'abord de trouver l'un de ces blocs pré-mis à zéro et de vous le donner - et il en trouvera probablement un.
Pavel Minaev
28
J'ai tendance à penser que si votre code devient "plus sûr" à la suite d'allocations à zéro par défaut, alors votre code n'est pas suffisamment sûr, que vous utilisiez malloc ou calloc. L'utilisation de malloc est un bon indicateur que les données doivent être initialisées - je n'utilise calloc que dans les cas où ces 0 octets sont réellement significatifs. Notez également que calloc ne fait pas nécessairement ce que vous pensez pour les types non-char. Personne n'utilise plus vraiment les représentations de piège, ou les flottants non-IEEE, mais ce n'est pas une excuse pour penser que votre code est vraiment portable quand il ne l'est pas.
Steve Jessop
18
@SteveJessop "Safer" n'est pas le bon mot. Je pense que "déterministe" est le meilleur terme. Un code plus déterministe que d'avoir des échecs qui dépendent du timing et des séquences de données, sera plus facile à isoler les échecs. Calloc est parfois un moyen facile d'obtenir ce déterminisme, par opposition à l'initialisation explicite.
dennis
362

Une différence moins connue est que dans les systèmes d'exploitation avec une allocation de mémoire optimiste, comme Linux, le pointeur renvoyé par mallocn'est pas soutenu par de la mémoire réelle jusqu'à ce que le programme le touche réellement.

calloctouche en effet la mémoire (il y écrit des zéros) et donc vous serez sûr que le système d'exploitation sauvegarde l'allocation avec de la RAM réelle (ou swap). C'est aussi pourquoi il est plus lent que malloc (non seulement il doit le mettre à zéro, le système d'exploitation doit également trouver une zone de mémoire appropriée en échangeant éventuellement d'autres processus)

Voir par exemple cette question SO pour plus de détails sur le comportement de malloc

Isak Savo
la source
49
callocpas besoin d'écrire des zéros. Si le bloc alloué se compose principalement de nouvelles pages nulles fournies par le système d'exploitation, il peut les laisser intactes. Bien sûr, cela nécessite callocd'être réglé sur le système d'exploitation plutôt que sur une fonction de bibliothèque générique malloc. Ou, un implémenteur pourrait faire calloccomparer chaque mot à zéro avant de le mettre à zéro. Cela ne ferait pas gagner de temps, mais cela éviterait de salir les nouvelles pages.
R .. GitHub ARRÊTEZ D'AIDER LA GLACE
3
@R .. note intéressante. Mais en pratique, de telles implémentations existent-elles à l'état sauvage?
Isak Savo
10
Toutes les dlmallocimplémentations similaires ignorent memsetsi le bloc a été obtenu via de mmapnouvelles pages anonymes (ou équivalent). Habituellement, ce type d'allocation est utilisé pour les gros morceaux, à partir de 256 Ko environ. Je ne connais aucune implémentation qui fasse la comparaison avec zéro avant d'écrire zéro à part la mienne.
R .. GitHub ARRÊTEZ D'AIDER LA GLACE
1
omallocsaute également le memset; callocn'a jamais besoin de toucher à des pages qui ne sont pas déjà utilisées par l'application (cache de pages). Cependant, les callocimplémentations extrêmement primitives diffèrent.
mirabilos
10
Le calloc de glibc vérifie s'il obtient de la mémoire fraîche du système d'exploitation. Si tel est le cas, il sait qu'il n'a PAS besoin de l'écrire, car mmap (..., MAP_ANONYMOUS) renvoie une mémoire déjà mise à zéro.
Peter Cordes
112

Un avantage souvent négligé callocest que (implémentations conformes de) il vous aidera à vous protéger contre les vulnérabilités de débordement d'entier. Comparer:

size_t count = get_int32(file);
struct foo *bar = malloc(count * sizeof *bar);

contre.

size_t count = get_int32(file);
struct foo *bar = calloc(count, sizeof *bar);

Le premier pourrait entraîner une petite allocation et des dépassements de tampon ultérieurs, s'il countest supérieur à SIZE_MAX/sizeof *bar. Ce dernier échouera automatiquement dans ce cas car un objet de cette taille ne peut pas être créé.

Bien sûr, vous devrez peut-être être à la recherche d'implémentations non conformes qui ignorent simplement la possibilité de débordement.

R .. GitHub ARRÊTER D'AIDER LA GLACE
la source
17
Apparemment, le débordement arithmétique a été à l'origine du trou d'OpenSSH en 2002. Bon article d'OpenBSD sur les dangers de cela avec des fonctions liées à la mémoire: undeadly.org/cgi?action=article&sid=20060330071917
Philip P.
4
@KomradeP .: Intéressant. Malheureusement, l'article que vous avez lié contient des informations erronées dès le début. L'exemple avec charn'est pas un débordement mais plutôt une conversion définie par l'implémentation lors de la réaffectation du résultat dans un charobjet.
R .. GitHub STOP HELPING ICE
Il est probablement là uniquement à des fins d'illustration. Parce que le compilateur est susceptible d'optimiser cela de toute façon. Le mien se compile dans cet asm: pousser 1.
Philip P.
1
@tristopia: Le fait n'est pas que le code est exploitable sur toutes les implémentations, mais qu'il est incorrect sans hypothèses supplémentaires et donc pas une utilisation correcte / portable.
R .. GitHub STOP HELPING ICE
3
@tristopia: Si votre mode de pensée est " size_t64 bits donc ce n'est pas un problème", c'est une façon de penser erronée qui va conduire à des bugs de sécurité. size_test un type abstrait qui représente des tailles, et il n'y a aucune raison de penser que le produit arbitraire d'un nombre 32 bits et d'un size_t(remarque: sizeof *barpourrait en principe être supérieur à 2 ^ 32 sur une implémentation C 64 bits!) s'intègre size_t.
R .. GitHub STOP HELPING ICE
37

La documentation fait ressembler le calloc à malloc, qui initialise simplement la mémoire à zéro; ce n'est pas la principale différence! L'idée de calloc est d'abstraire la sémantique de copie sur écriture pour l'allocation de mémoire. Lorsque vous allouez de la mémoire avec calloc, tout est mappé sur la même page physique qui est initialisée à zéro. Lorsqu'une des pages de la mémoire allouée est écrite dans une page physique est allouée. Ceci est souvent utilisé pour créer des tables de hachage ÉNORMES, par exemple car les parties de hachage vides ne sont pas soutenues par une mémoire supplémentaire (pages); ils pointent joyeusement vers la page unique initialisée à zéro, qui peut même être partagée entre les processus.

Toute écriture sur une adresse virtuelle est mappée sur une page, si cette page est la page zéro, une autre page physique est allouée, la page zéro y est copiée et le flux de contrôle est renvoyé au processus client. Cela fonctionne de la même manière que les fichiers mappés en mémoire, la mémoire virtuelle, etc. fonctionnent .. il utilise la pagination.

Voici une histoire d'optimisation sur le sujet: http://blogs.fau.de/hager/2007/05/08/benchmarking-fun-with-calloc-and-zero-pages/

t0rakka
la source
26

Il n'y a aucune différence dans la taille du bloc de mémoire alloué. callocremplit simplement le bloc de mémoire avec un motif physique de zéro. Dans la pratique, on suppose souvent que les objets situés dans le bloc de mémoire alloué avec callocont une valeur initiale comme s'ils avaient été initialisés avec un littéral 0, c'est-à-dire que les entiers devraient avoir la valeur de 0, les variables à virgule flottante - la valeur de0.0 , les pointeurs - la pointeur nul appropriée , etc.

Du point de vue pédant cependant, 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 ce qu'on appelle une représentation d'interruption , ce qui provoque un comportement non défini. En d'autres termes, pour tout type autre que unsigned charle motif tout-à-zéro susmentionné, il pourrait représenter une valeur illégale, une représentation d'interruption.

Plus tard, dans l'un des rectificatifs techniques à la norme C99, le comportement a été défini pour tous les types d'entiers (ce qui est logique). Autrement dit, dans le langage C actuel, vous ne pouvez initialiser que les types entiers avec calloc(et memset(..., 0, ...)). L'utiliser pour initialiser autre chose dans le cas général conduit à un comportement indéfini, du point de vue du langage C.

En pratique, callocça marche, comme nous le savons tous :), mais c'est à vous de décider si vous souhaitez l'utiliser (compte tenu de ce qui précède). Personnellement, je préfère l'éviter complètement, utiliser à la mallocplace et effectuer ma propre initialisation.

Enfin, un autre détail important est celui qui callocest nécessaire pour calculer la taille finale du bloc en interne , en multipliant la taille des éléments par le nombre d'éléments. Ce faisant, vous callocdevez surveiller les éventuels débordements arithmétiques. Il en résultera une allocation infructueuse (pointeur nul) si la taille de bloc demandée ne peut pas être calculée correctement. Pendant ce temps, votre mallocversion n'essaie pas de surveiller les débordements. Il allouera une certaine quantité de mémoire "imprévisible" en cas de débordement.

Fourmi
la source
Par le paragraphe "autre détail important": cela semble poser memset(p, v, n * sizeof type);problème car il n * sizeof typepeut déborder. Je suppose que je devrai utiliser une for(i=0;i<n;i++) p[i]=v;boucle pour un code robuste.
chux
Il serait utile qu'il existe un moyen standard par lequel le code pourrait affirmer qu'une implémentation doit utiliser all-bits-zero comme pointeur nul (refusant la compilation sinon), car il existe des implémentations qui utilisent d'autres représentations de pointeur nul, mais elles sont relativement rare; le code qui n'a pas à s'exécuter sur de telles implémentations peut être plus rapide s'il peut utiliser calloc () ou memset pour initialiser des tableaux de pointeurs.
supercat
@chux Non, si un tableau avec des néléments existe là où un élément a la taille sizeof type, il n*sizeof typene peut pas déborder, car la taille maximale de tout objet doit être inférieure à SIZE_MAX.
12431234123412341234123
@ 12431234123412341234123 vrai sur un tableau taille <= SIZE_MAX, mais il n'y a pas de tableaux ici. Le pointeur renvoyé par calloc()peut pointer vers la mémoire allouée qui dépasse SIZE_MAX. De nombreuses implémentations limitent le produit des 2 arguments calloc()à SIZE_MAX, mais la spécification C n'impose pas cette limite.
chux
21

extrait d'un article Benchmarking fun with calloc () and zero pages on Georg Hager's Blog

Lors de l'allocation de mémoire à l'aide de calloc (), la quantité de mémoire demandée n'est pas allouée immédiatement. Au lieu de cela, toutes les pages qui appartiennent au bloc de mémoire sont connectées à une seule page contenant tous les zéros par une magie MMU (liens ci-dessous). Si de telles pages sont uniquement lues (ce qui était vrai pour les tableaux b, c et d dans la version originale du test de performances), les données sont fournies à partir de la page zéro unique, qui - bien sûr - tient dans le cache. Voilà pour les noyaux de boucles liés à la mémoire. Si une page est écrite (quelle que soit la manière), une erreur se produit, la page «réelle» est mappée et la page zéro est copiée en mémoire. C'est ce qu'on appelle la copie sur écriture, une approche d'optimisation bien connue (que j'ai même enseignée plusieurs fois dans mes conférences C ++). Après ça,

Ashish Chavan
la source
où est le lien?
Rupesh Yadav.
2
la première ligne de réponse contient un lien vers le blog de Georg Hager.
Ashish Chavan
11

callocest généralement malloc+memsetà 0

Il est généralement légèrement préférable d'utiliser malloc+memsetexplicitement, surtout lorsque vous faites quelque chose comme:

ptr=malloc(sizeof(Item));
memset(ptr, 0, sizeof(Item));

C'est mieux car il sizeof(Item)est connu du compilateur au moment de la compilation et le compilateur le remplacera dans la plupart des cas par les meilleures instructions possibles pour mettre à zéro la mémoire. D'un autre côté, si cela memsetse produit calloc, la taille du paramètre de l'allocation n'est pas compilée dans le calloccode et réel memsetest souvent appelé, qui contiendrait généralement du code pour effectuer le remplissage octet par octet jusqu'à la limite longue, puis cycle pour remplir la mémoire en sizeof(long)morceaux et enfin le remplissage octet par octet de l'espace restant. Même si l'allocateur est suffisamment intelligent pour en appeler, aligned_memsetce sera toujours une boucle générique.

Une exception notable serait lorsque vous faites malloc / calloc d'une très grande partie de la mémoire (quelques power_of_two kilobytes), auquel cas l'allocation peut être effectuée directement à partir du noyau. Comme les noyaux de système d'exploitation mettent généralement à zéro toute la mémoire qu'ils donnent pour des raisons de sécurité, un calloc suffisamment intelligent peut simplement le renvoyer sans mise à zéro supplémentaire. Encore une fois - si vous allouez simplement quelque chose que vous savez petit, vous pourriez être mieux avec malloc + memset en termes de performances.

virco
la source
+1 pour le rappel qu'une implémentation générique d'une fonctionnalité dans une bibliothèque système n'est pas nécessairement plus rapide que la même opération dans le code utilisateur.
Patrick Schlüter
1
Il y a aussi un deuxième point qui rend calloc()plus lent que malloc(): la multiplication pour la taille. calloc()est nécessaire pour utiliser une multiplication générique (si size_test 64 bits même l'opération très coûteuse 64 bits * 64 bits = 64 bits) tandis que le malloc () aura souvent une constante de temps de compilation.
Patrick Schlüter
4
glibc calloc a quelques astuces pour décider comment effacer le plus efficacement le morceau retourné, par exemple parfois seulement une partie de celui-ci a besoin d'être effacé, et aussi un effacement déroulé jusqu'à 9 * sizeof (size_t). La mémoire est de la mémoire, l'effacer de 3 octets à la fois ne sera pas plus rapide simplement parce que vous allez ensuite l'utiliser pour la conserver struct foo { char a,b,c; };. callocvaut toujours mieux que malloc+ memset, si vous voulez toujours effacer toute la mallocrégion ed. calloca également une vérification minutieuse mais efficace des débordements int dans les éléments size *.
Peter Cordes
8

Différence 1:

malloc() alloue généralement le bloc de mémoire et il est un segment de mémoire initialisé.

calloc() alloue le bloc de mémoire et initialise tout le bloc de mémoire à 0.

Différence 2:

Si vous considérez la malloc()syntaxe, elle ne prendra qu'un seul argument. Considérez l'exemple suivant ci-dessous:

data_type ptr = (cast_type *)malloc( sizeof(data_type)*no_of_blocks );

Ex: si vous souhaitez allouer 10 blocs de mémoire pour le type int,

int *ptr = (int *) malloc(sizeof(int) * 10 );

Si vous considérez la calloc()syntaxe, cela prendra 2 arguments. Considérez l'exemple suivant ci-dessous:

data_type ptr = (cast_type *)calloc(no_of_blocks, (sizeof(data_type)));

Ex: si vous voulez allouer 10 blocs de mémoire pour le type int et initialiser tout cela à ZERO,

int *ptr = (int *) calloc(10, (sizeof(int)));

Similarité:

Les deux malloc()et calloc()renverront void * par défaut s'ils ne sont pas transtypés.!

Shivaraj Bhat
la source
Et pourquoi gardez-vous data_type et cast_type différents?
Épuisé
7

Il y a deux différences.
Tout d'abord, c'est dans le nombre d'arguments. malloc()prend un seul argument (mémoire requise en octets), alors qu'il a calloc()besoin de deux arguments.
Deuxièmement, malloc()n'initialise pas la mémoire allouée, tout en calloc()initialisant la mémoire allouée à ZERO.

  • calloc()alloue une zone mémoire, la longueur sera le produit de ses paramètres. callocremplit la mémoire de ZÉRO et renvoie un pointeur sur le premier octet. S'il ne parvient pas à localiser suffisamment d'espace, il renvoie un NULLpointeur.

Syntaxe: ptr_var=(cast_type *)calloc(no_of_blocks , size_of_each_block); ieptr_var=(type *)calloc(n,s);

  • malloc()alloue un seul bloc de mémoire de REQUSTED SIZE et renvoie un pointeur sur le premier octet. S'il ne parvient pas à localiser la quantité de mémoire requise, il renvoie un pointeur nul.

Syntaxe: ptr_var=(cast_type *)malloc(Size_in_bytes); la malloc()fonction prend un argument, qui est le nombre d'octets à allouer, tandis que la calloc()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. En outre, calloc()initialise l'espace alloué à des zéros, alors malloc()qu'il ne le fait pas.

Jainendra
la source
6

La calloc()fonction qui est déclarée dans l'en- <stdlib.h>tête offre quelques avantages par rapport à la malloc()fonction.

  1. Il alloue de la mémoire comme un certain nombre d'éléments d'une taille donnée, et
  2. Il initialise la mémoire allouée afin que tous les bits soient nuls.
Vipin Diwakar
la source
6

malloc()et calloc()sont des fonctions de la bibliothèque standard C qui permettent l'allocation dynamique de la mémoire, ce qui signifie qu'elles permettent toutes les deux l'allocation de la mémoire pendant l'exécution.

Leurs prototypes sont les suivants:

void *malloc( size_t n);
void *calloc( size_t n, size_t t)

Il y a principalement deux différences entre les deux:

  • Comportement: malloc()alloue un bloc de mémoire, sans l'initialiser, et la lecture du contenu de ce bloc entraînera des valeurs inutiles. calloc(), d'autre part, alloue un bloc de mémoire et l'initialise à zéro, et évidemment la lecture du contenu de ce bloc se traduira par des zéros.

  • Syntaxe: malloc()prend 1 argument (la taille à allouer) et calloc()prend deux arguments (nombre de blocs à allouer et taille de chaque bloc).

La valeur de retour des deux est un pointeur sur le bloc de mémoire alloué, en cas de succès. Sinon, NULL sera renvoyé, indiquant l'échec de l'allocation de mémoire.

Exemple:

int *arr;

// allocate memory for 10 integers with garbage values
arr = (int *)malloc(10 * sizeof(int)); 

// allocate memory for 10 integers and sets all of them to 0
arr = (int *)calloc(10, sizeof(int));

Les mêmes fonctionnalités que celles qui calloc()peuvent être obtenues en utilisant malloc()et memset():

// allocate memory for 10 integers with garbage values   
arr= (int *)malloc(10 * sizeof(int));
// set all of them to 0
memset(arr, 0, 10 * sizeof(int)); 

Notez qu'il malloc()est de préférence utilisé calloc()car il est plus rapide. Si vous souhaitez initialiser les valeurs à zéro, utilisez calloc()plutôt.

elmiomar
la source
5

Une différence pas encore mentionnée: taille limite

void *malloc(size_t size)ne peut allouer que jusqu'à SIZE_MAX.

void *calloc(size_t nmemb, size_t size);peut allouer environ SIZE_MAX*SIZE_MAX.

Cette capacité n'est pas souvent utilisée dans de nombreuses plates-formes avec adressage linéaire. De tels systèmes se limitent calloc()à nmemb * size <= SIZE_MAX.

Considérons un type de 512 octets appelé disk_sectoret le code veut utiliser beaucoup de secteurs. Ici, le code ne peut utiliser que des SIZE_MAX/sizeof disk_sectorsecteurs.

size_t count = SIZE_MAX/sizeof disk_sector;
disk_sector *p = malloc(count * sizeof *p);

Considérez ce qui suit qui permet une allocation encore plus importante.

size_t count = something_in_the_range(SIZE_MAX/sizeof disk_sector + 1, SIZE_MAX)
disk_sector *p = calloc(count, sizeof *p);

Maintenant, si un tel système peut fournir une allocation aussi importante, c'est une autre affaire. La plupart aujourd'hui ne le feront pas. Pourtant, cela s'est produit pendant de nombreuses années quand il SIZE_MAXétait 65535. Compte tenu de la loi de Moore , soupçonnez que cela se produira vers 2030 avec certains modèles de SIZE_MAX == 4294967295mémoire et des pools de mémoire dans les 100 Go.

chux - Réintégrer Monica
la source
2
Généralement, size_t sera capable de contenir la taille du plus grand type d'objet qu'un programme pourrait gérer. Un système où size_t est de 32 bits est peu susceptible de pouvoir gérer une allocation supérieure à 4294967295 octets, et un système qui serait capable de gérer des allocations de cette taille ferait presque certainement size_tplus de 32 bits. La seule question est de savoir si l'utilisation callocavec des valeurs dont le produit dépasse SIZE_MAXpeut être invoquée pour produire zéro plutôt que de renvoyer un pointeur vers une allocation plus petite.
supercat
Soyez d'accord sur votre généralisation , mais la spécification C permet des calloc()allocations supérieures SIZE_MAX. Cela s'est produit dans le passé avec 16 bits size_tet comme la mémoire continue de diminuer, je ne vois aucune raison pour que cela ne se produise pas, même si ce n'est pas courant .
chux
1
La norme C permet au code de demander une allocation dont la taille dépasse SIZE_MAX. Cela n'exige certainement pas qu'il y ait des circonstances dans lesquelles une telle allocation pourrait réussir; Je ne suis pas sûr qu'il y ait un avantage particulier à exiger que les implémentations qui ne peuvent pas gérer de telles allocations doivent retourner NULL(d'autant plus qu'il est courant pour certaines implémentations d'avoir des mallocpointeurs de retour vers un espace qui n'est pas encore validé et qui pourrait ne pas être disponible lorsque le code essaie réellement d'utiliser il).
supercat
De plus, là où il pouvait y avoir dans le passé des systèmes dont la plage d'adressage disponible dépassait le plus grand entier représentable, je ne vois aucune possibilité réaliste que cela se reproduise, car cela nécessiterait une capacité de stockage de milliards de gigaoctets. Même si la loi de Moore continuait de s'appliquer, passer du point où 32 bits cesserait d'être suffisant au point où 64 bits cesserait d'être suffisant prendrait deux fois plus de temps que de passer du point où 16 bits suffisait au point où 32 n'était pas 't.
supercat
1
Pourquoi une mise en œuvre qui peut accueillir une allocation unique supérieure à la 4G ne se définirait-elle size_tpas uint64_t?
supercat du
2

Nombre de blocs:
malloc () affecte un seul bloc de mémoire demandée,
calloc () affecte plusieurs blocs de la mémoire demandée

Initialisation:
malloc () - n'efface pas et n'initialise pas la mémoire allouée.
calloc () - initialise la mémoire allouée par zéro.

Vitesse:
malloc () est rapide.
calloc () est plus lent que malloc ().

Arguments et syntaxe:
malloc () prend 1 argument:

  1. octets

    • Le nombre d'octets à allouer

calloc () prend 2 arguments:

  1. longueur

    • le nombre de blocs de mémoire à allouer
  2. octets
    • le nombre d'octets à allouer à chaque bloc de mémoire
void *malloc(size_t bytes);         
void *calloc(size_t length, size_t bytes);      

Manière d'allocation de mémoire:
La fonction malloc attribue de la mémoire de la «taille» souhaitée à partir du tas disponible.
La fonction calloc attribue à la mémoire la taille de ce qui est égal à 'num * size'.

Signification du nom:
Le nom malloc signifie "allocation de mémoire".
Le nom calloc signifie "allocation contiguë".

Majbah Habib
la source