11
votes

Comment savez-vous combien d'espace allouer avec MALLOC ()?

Je suis un Total C New Yewbie, je viens de C #. J'ai appris sur la gestion de la mémoire et la fonction malloc () code>. J'ai également rencontré ce code:

char *a_persons_name = malloc(sizeof(char) + 2);


0 commentaires

6 Réponses :


1
votes

Votre appel à MALLOC allouera 3 octets de mémoire. Tailleof (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 terminaison)


0 commentaires

18
votes

Cet extrait est l'allocation suffisamment d'espace pour un nom de 2 caractères.

Généralement, le tampon à cordes va être rempli de quelque part, c'est-à-dire des E / S. Si la taille de la chaîne n'est pas connue à l'avance (par exemple, la lecture d'un fichier ou de clavier), l'une des trois approches est généralement utilisée:

  • Définissez une taille maximale pour une chaîne donnée, allocation de cette taille + 1 (pour le terminateur NULL), lisez au maximum que de nombreux caractères et erreurs ou tronquent aveuglément si de trop de caractères ont été fournis. Pas terriblement convivial.

  • réaffecter des étapes (de préférence à l'aide de séries géométriques, par exemple doublement, pour éviter le comportement quadratique) et continuer à lire jusqu'à ce que la fin soit atteinte. Pas terriblement facile à coder.

  • allouer une taille fixe et espérons qu'il ne sera pas dépassé et crash (ou être possédé) horriblement lorsque cette hypothèse échoue. Facile à coder, facile à casser. Par exemple, voir obtient dans la bibliothèque C Standard C. ( N'utilisez jamais cette fonction. )


12 commentaires

Pourquoi faire tous les moyens d'allouer suffisamment d'espace sucer? N'y a-t-il pas facile!


Les chaînes sont la partie la plus brisée de C. Je recommande de coder une structure pseudo-oo «Stringbuilder» ou similaire et créant des paragraphes. Strbufprintf, Strbufgets, Strbufscanf, etc. pour centraliser ce type d'opérations. La bibliothèque C Standard C aident beaucoup. C ++ est légèrement meilleur, car vous avez généralement 10 de classes de chaîne différentes, une pour chaque cadre distinct utilisé. Oui, je suis sarcastique.


Le moyen facile est d'utiliser (1) utiliser une langue dans laquelle une chaîne est un type de base; (2) Utilisez une bibliothèque qui fournit un comportement de chaîne; ou (3) apprendre la langue que vous utilisez. Si vous ne voulez pas apprendre à utiliser les outils, pourquoi essayez-vous même. Trouvez une autre langue qui vous convient le plus (je n'essaye pas d'insulter ici, juste pragmatique).


@Pax: Je voulais vraiment apprendre les fondamentaux de C afin que je puisse aider à contribuer à Gedit (que je connaisse est écrit en C et utilise GTK). Je pensais qu'il serait préférable d'apprendre tout ce que je pouvais sur la gestion de la mémoire avant de faire quoi que ce soit avec un véritable programme (grand). Cela étant dit, si je vais écrire un programme, cela va être fait en C #.


Ce n'est pas vraiment que les cordes sont cassées en c. C'est que les cordes sont étonnamment difficiles à faire correctement, et c fournit peu de soutien au-dessus du métal nu. Langue qui fournit des chaînes «faciles» ont beaucoup sur le capot (chacun d'entre eux).


Une langue dans laquelle le moyen le plus simple de faire des cordes est la mauvaise façon de faire des cordes et la bibliothèque standard comprend un exemple de mauvais sens, semble brisé en ce qui concerne les ficelles pour moi.


@Lucasa, vous trouverez peut-être que GTK fournit également un code d'abstraction pour les chaînes. Glib contient une abstraction de gstring (et des listes et d'autres personnes) qui peuvent faciliter votre vie. Je ne préconise pas de ne pas apprendre à quel point le métal c Strings (vous devriez), indiquant que cela ne peut pas être absolument nécessaire pour le domaine qui vous intéresse.


@Barryk, les chaînes sont faciles à faire en C si vous savez ce que vous faites. J'ai un code de traitement de chaîne C que j'ai écrit dans '84 qui n'a pas été mis à jour depuis 1996 et cela me donne tout ce dont j'ai besoin. Oui, de nombreuses choses sont difficiles à faire dans la langue de base C mais c'est l'une des raisons pour lesquelles vous avez des fonctions. Vous pouvez donc abstraire les difficultés - vous ne devez que cela une fois, puis amortiez le coût sur toute votre carrière.


Et dire que c est cassé est la même chose que de dire que c ++ est cassé car il ne peut pas faire des entiers 256 bits ou les deux sont cassés en raison de la précision limitée du point flottant - ils sont ce qu'ils sont. Broken signifie "ne correspond pas à la spécification", pas "pourrait être mieux fait" (imnsho).


Les cordes ne sont pas transparentes en C parce que c non une langue de haut niveau: vous pouvez toujours voir le métal nu de c, et rien n'est caché. Si vous voulez des chaînes qui "fonctionnent simplement", vous devez le donner. Plaintes concernant la bibliothèque standard que je reçois, mais c'est le résultat de l'histoire: cette bibliothèque a été développée sur des commandes de magnitude de machines moins puissantes que votre téléphone portable.


Bien sûr, les chaînes sont faciles en C aussi longtemps que vous construisez les abstractions appropriées vous-même. Mais parlant en tant que concepteur de langue et de mise en œuvre, je pense que c'est un fait que c a été presque seul responsable de millions de millions, voire des milliards de dollars de dollars de dommages à l'approche particulièrement faible des chaînes.


La puissance de la machine n'excuse pas le manque d'exactitude de la mise en œuvre.



5
votes

Eh bien, pour un démarrage, Tailleof (Char) est toujours 1, de sorte que vous pourriez simplement malloc (3) .

Qu'est-ce que vous allocez il y a assez d'espace pour trois personnages. Mais gardez à l'esprit que vous en avez besoin d'un pour un terminateur nul pour C Strings.

Ce que vous avez tendance à trouver, c'est des choses comme: xxx

pour obtenir suffisamment de stockage Pour un nom de nom et de terminaison (gardant à l'esprit que la chaîne "xzezy" est stockée en mémoire comme suit: xxx

parfois avec des tableaux non caractères à base de caractères, vous verrez: xxx

qui allouera suffisamment d'espace pour 22 entiers.


4 commentaires

(type et commodité) int * intarray = malloc (taille de (* intarray) * 22);


"Eh bien, pour un début, la taille de (caractère) est toujours de 1" faux. C Spécifie 1 octet comme une limite inférieure pour la taille d'un caractère. La taille réelle est à la fois l'architecture et le compilateur. Sur certaines arcitectures obscures, un caractère est de 16 bits.


Non, en fait, la taille de (char) est toujours 1. de C1X, "6.5.3.4 la taille de l'opérateur", paragraphe 3: lorsqu'il est appliqué à un opérande qui a du type de caractères, de caractère non signé ou de caractères signés , (ou une version qualifiée de celle-ci) le résultat est de 1.


Voir Stackoverflow.com/Questions/ 1535131 / ... Pour plus de détails: Le C STD définit l'octet comme unité adressable, mais ce n'est pas nécessairement un octet 8 bits (octet).



1
votes

Cela allouera trois octets; 1 pour la taille de (char), plus deux. Il suffit de voir cette ligne hors contexte, je n'ai aucun moyen de savoir pourquoi il serait alloué de cette façon ou si cela est correct (ça me convient).

Vous devez attribuer suffisamment de mémoire pour tenir ce que vous devez y mettre. Par exemple, si vous allouez la mémoire pour contenir une chaîne, vous devez attribuer suffisamment de mémoire pour maintenir la chaîne la plus longue attendue plus un octet pour la null de terminaison. Si vous traitez avec 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.


0 commentaires

3
votes

MALLOC () code> allouera un bloc de mémoire et renvoyera un pointeur à cette mémoire s'il réussit, et null s'ils sont infructueux. La taille du bloc de la mémoire est spécifiée par malloc code> S, en octets.

the Taille de l'opérateur code> donne la taille de son argument en octets. P >

char *someString = malloc(10);
strcpy(someString, "Hello there, world!");
printf("%s\n", someString);


0 commentaires

1
votes

Premier point - c'est une bonne habitude de ne jamais mettre de chiffres absolus dans l'argument à Malloc, utilisez toujours la taille de la taille et un multiple. Comme indiqué ci-dessus, la mémoire allouée à certains types varie avec le compilateur et la plate-forme. Afin de garantir suffisamment d'espace pour un tableau de type 'Blob', il est préférable d'utiliser quelque chose comme ceci:

const char str1 = "Hello";
char *str2 = malloc(sizeof(char) * (strlen(str1) + 1));
strcpy(str2, str1);


1 commentaires

1) En désaccord avec "Mieux vaut utiliser quelque chose comme ceci:" p_data = malloc (taille de (blob) * longueur_of_array); p_data = malloc (taille de * p_data * longueur_of_array); Comme cela ne dépend pas de coder le type de type et de la garder juste comme des changements de code. 2) Exemple d'utilisation: str2 = malloc (taille de * str2 * (Strlen (str1) + 1));