Comment savez-vous de combien d'espace à allouer avec malloc()?
Je suis un total C newbie, je viens du C#. J'ai appris à propos de la gestion de la mémoire et de la malloc()
fonction. J'ai aussi tombé sur ce code:
char *a_persons_name = malloc(sizeof(char) + 2);
Ce que je ne comprends pas, c'est comment beaucoup d'espace, c'est l'allocation pour a_persons_name
. Est-il allouer 2 caractères (par exemple. AB) ou autre chose?
Je sais aussi que vous pouvez parfois obtenir un peu de "chance" avec malloc
et l'utilisation de l'espace non alloué (ce qui peut entraîner la corruption des données et seg défauts). Alors, comment puis-je savoir combien d'espace je suis l'allocation et de la façon dont j'aurai besoin?
OriginalL'auteur Kredns | 2009-08-08
Vous devez vous connecter pour publier un commentaire.
Ce morceau de code est d'allouer suffisamment d'espace pour un 2-nom du personnage.
Généralement le tampon de chaîne va être rempli de quelque part, c'est à dire I/O. Si la taille de la chaîne n'est pas connu à l'avance (par exemple, de la lecture du fichier ou le clavier), l'une des trois approches sont généralement utilisées:
Définir une taille maximale pour toute chaîne de caractères, allouer que la taille de + 1 (pour le terminateur null), lire au plus que le nombre de caractères, et l'erreur ou à l'aveuglette tronquer si un trop grand nombre de personnages ont été fournis. Pas très convivial.
Réaffecter dans les stades (de préférence à l'aide de série géométrique, par exemple, de doubler, pour éviter quadratique comportement), et continuer à lire jusqu'à la fin a été atteint. Pas très facile à coder.
Allouer une taille fixe et j'espère qu'il ne sera pas dépassé, et de crash (ou la propriété) horriblement lorsque cette hypothèse omet. Facile à code, facile à briser. Voir, par exemple,
gets
dans la bibliothèque standard C. (Ne jamais utiliser cette fonction.)Les chaînes sont les plus partie cassée de C. je recommande le codage d'un pseudo-OO 'StringBuilder' struct ou similaire, et en créant par exemple StrBufPrintf, StrBufGets, StrBufScanf, etc. afin de centraliser ce genre d'opérations. La bibliothèque standard C ne l'aide pas beaucoup. C++ est un peu mieux, parce que vous avez généralement 10s de différentes classes de chaînes de caractères à choisir, un pour chaque distinctes de cadre utilisé. Oui, je suis sarcastique.
Le plus simple est soit (1) l'utilisation d'un langage où une chaîne est un type de base; (2) utiliser une bibliothèque qui fournit le comportement d'une chaîne; ou (3) apprendre la langue que vous utilisez. Si vous ne voulez pas apprendre comment utiliser les outils, pourquoi êtes-vous à même d'essayer. Trouver une autre langue, c'est plus adaptée pour vous (je ne cherche pas à être insultant, ici, juste pragmatique).
Une langue dans laquelle le moyen le plus facile pour faire des cordes est la mauvaise manière de faire des chaînes, et la bibliothèque standard comprend un exemple de la mauvaise façon, semble rompu à l'égard des chaînes de moi.
Pour sûr, les chaînes sont facile en C aussi longtemps que vous les ressources des abstractions vous-même. Mais en parlant comme une langue de concepteur et de réalisateur, je crois que c'est un fait que C est presque à lui seul responsable de millions, voire des milliards, de dollars de dommages par le biais de son notamment la faiblesse de l'approche des chaînes de caractères.
OriginalL'auteur Barry Kelly
Bien, pour commencer,
sizeof(char)
est toujours de 1, de sorte que vous pouvez simplementmalloc(3)
.Ce que vous allouez il y a assez d'espace pour les trois personnages. Mais gardez à l'esprit dont vous avez besoin pour un terminateur null pour les chaînes C.
Ce que vous avez tendance à trouver est des choses comme:
pour obtenir suffisamment d'espace de stockage pour un nom et un caractère de fin (en gardant à l'esprit que la chaîne "xyzzy" est stocké dans la mémoire comme:
Parfois avec des non-char à base de tableaux, vous verrez:
qui permettra d'allouer suffisamment d'espace pour 22 entiers.
int *intArray = malloc(sizeof(*intArray) * 22);
"Eh bien, pour commencer, sizeof(char) est toujours de 1" FALSE. C spécifie 1 octet comme une des LIMITES INFÉRIEURES à la taille d'un char. La taille réelle est à la fois l'architecture et le compilateur dépendante. Sur certains plus obscurs arcitectures un char est de 16 bits.
Non, en fait, sizeof(char) est toujours 1. De c1x, "6.5.3.4 L'opérateur sizeof", para 3: Lorsqu'il est appliqué à un opérande qui est de type char, unsigned char, ou signed char, (ou d'une version de celui-ci), le résultat est 1.
Voir stackoverflow.com/questions/1535131/... pour plus de détails: la C std octet définit comme l'unité adressable mais ce n'est pas nécessairement un octet de 8 bits (octet).
OriginalL'auteur paxdiablo
malloc()
va allouer un bloc de mémoire et retourne un pointeur sur la mémoire en cas de succès, et NULL en cas d'échec. la taille du bloc de mémoire est spécifié parmalloc
'argument, en octets.la
sizeof
opérateur donne la taille de son argument en octets.cela permettra d'allouer suffisamment d'espace pour un 49 chaîne de caractères (un C-style chaîne doit se terminer par un NUL (
'\0'
) caractère), non compris le caractère NUL, et le point desomeString
à ce mémoire.Il semble que ce code dans votre question devrait être
malloc(sizeof(char) * 2);
, commesizeof(char) + 2
ne fait pas de sens.noter que
sizeof(char)
est garanti pour toujours égale à 1 (octet) -- mais la mémoire de la représentation des autres types (tels que long) peuvent varier entre les compilateurs.La façon que vous avez (de l'onu)de la chance avec la mémoire allouée dynamiquement est si vous essayez de lire/écrire en dehors de la mémoire allouée.
Par exemple,
La première ligne alloue suffisamment de place pour 9 caractères et un caractère NULL.
La deuxième ligne tente de copier 20 caractères (19 + NULL) vers la mémoire de l'espace. Cette dépassements de la mémoire tampon et peut provoquer quelque chose d'incroyablement plein d'esprit, telles que l'écrasement de mémoire adjacentes, ou de provoquer une erreur de segmentation.
La troisième ligne pourrait fonctionner, par exemple, s'il a été alloué de la mémoire juste à côté de someString, et "Bonjour, monde!" est entré dans la mémoire de l'espace, il peut imprimer votre chaîne de plus tout ce qui était dans le prochain espace de mémoire. Si cette deuxième espace est NULL, il serait alors stop--à moins qu'il ne l'était pas, auquel cas il ne s'égare, et finalement erreur de segmentation.
Cet exemple est assez simple de fonctionnement, il est pourtant si facile de se tromper. C est délicat -- être prudent.
OriginalL'auteur Carson Myers
Votre appel à
malloc
va allouer 3 octets de mémoire.sizeof(char)
est de 1 octet et 2 octets sont indiqués explicitement. Cela vous donne assez d'espace pour une chaîne de taille 2 (avec le caractère de fin)OriginalL'auteur Brandon E Taylor
Cela va affecter des trois octets; 1 pour sizeof(char), plus deux. Il suffit de voir que la ligne de hors contexte, je n'ai aucun moyen de savoir pourquoi il reviendrait de cette façon, ou si elle est correcte (il semble louche pour moi).
Vous devez allouer suffisamment de mémoire pour stocker ce que vous avez besoin de mettre en elle. Par exemple, si vous êtes de l'allocation de mémoire pour contenir une chaîne, vous devez allouer suffisamment de mémoire pour contenir la chaîne la plus longue attendu plus d'un octet pour la valeur null. Si vous avez affaire à des chaînes ASCII, c'est facile: un octet par caractère plus un. Si vous utilisez des chaînes unicode, les choses deviennent plus compliquées.
OriginalL'auteur Fred Larson
Premier point - c'est une bonne habitude de ne jamais mettre des chiffres absolus dans l'argument de la fonction malloc, toujours utiliser sizeof et un multiples. Comme dit ci-dessus, la mémoire allouée pour certains types varie avec le compilateur et de la plate-forme. Afin de garantir gettin assez d'espace pour un tableau de type "blob" il est préférable d'utiliser quelque chose comme ceci:
De cette façon, quel que soit le type est, toutefois, il semble de mémoire que vous obtiendrez exactement la bonne quantité.
Deuxièmement, les erreurs de segmentation, etc.
C, est un langage de bas niveau, n'a pas de vérification des limites. Cela signifie qu'il n'y a rien à vérifier que vous êtes à la recherche à un indice pas réellement dans le tableau. En fait, il ne vous empêchera pas d'accéder à la mémoire de n'importe où, même si elle ne fait pas partie de votre programme (même si votre système d'exploitation, c'est ce une erreur de segmentation). C'est pourquoi, chaque fois que vous passez un tableau autour de en C, vous devez passer sa longueur, de sorte que la fonction de réception de la matrice sait comment elle est grande. N'oubliez pas qu'un 'tableau' est vraiment juste un pointeur vers le premier élément.
C'est très peu utile lors du passage de chaînes autour de chaque argument de la chaîne qui allait devenir deux arguments, donc un tricheur est utilisé. Toute norme de chaîne C est NULL. Le dernier caractère de la chaîne doit être la valeur ASCII de 0. Toutes les fonctions de chaîne de travail ainsi que le tableau jusqu'à ce qu'ils voient ça et puis stop. De cette façon, ils n'ont pas de dépassement de capacité de la pile, mais si elle n'est pas là pour une raison, ils le feront.
Cela étant compris
est de 5, mais à les stocker, il faut un caractère de plus. E. g.:
Et oui, sizeof(char) est inutile, car elle est définie à 1, mais je trouve ça plus clair et c'est vraiment une bonne habitude.
p_data = malloc(sizeof(blob) * length_of_array);
p_data = malloc(sizeof *p_data * length_of_array);
comme il ne dépend pas de codage du type droit et de le garder, de droite comme de modifications de code. 2) Exemple d'utilisation:str2 = malloc(sizeof *str2 * (strlen(str1) + 1));
OriginalL'auteur WillW