8
votes

Allocation de mémoire à char * c langue

Est-ce la bonne façon d'attribuer la mémoire à un caractère *.

char* sides ="5";

char* tempSides;

tempSides = (char*)malloc(strlen(inSides) * sizeof(char));


1 commentaires

@brickner Qu'en est-il de cela à Strlen, Strlen (Inside) + 1


7 Réponses :


17
votes

presque. Les chaînes sont terminées nulle, vous souhaitez probablement allouer un octet supplémentaire pour stocker l'octet nul. C'est, même si côtés est de 1 caractère long, il est vraiment 2 octets: { 5 , '\ 0' }.

Donc, ce serait: xxx

et si vous voulez le copier dans: xxx


9 commentaires

Vous voulez dire '\ 0' quand vous dites null. '\ 0' est nul, pas null.


Notez que la multiplication par Tailleof (Char) est inutile; Taillef (Char) est défini pour être 1.


@CAF: True, mais omission que cela rend plus difficile d'adapter le code à WCHAR_T ou à TCHAR si nécessaire - s'il n'y a pas de multiplications, il y a un risque d'oublier d'en utiliser un.


N'oubliez pas de vérifier NULL avant le Strcpy


@shachartooth: Multiplier par Tailleof * Tempsures serait le mieux si vous êtes préoccupé par la commutation sur wchar_t plus tard.


@George Phillips: Strictement parlant, vous voulez dire «caractère null». nul est le moniker ASCII pour le caractère null; Le terme «nul» n'apparaît nulle part dans la norme C.


@R Samuel Klatchko: Comment proposez-vous de faire un tel chèque et quelles seraient les conséquences possibles? S'il n'y a pas de \ 0 après l'entrée, strallen () et Strcpy échouerait de la même manière que votre vérification proposée.


@Msalters: Il voulait dire vérifier la valeur de retour MALLOC .


J'utiliserais strncpy au lieu de strcpy . Dans ce cas, nous savons que le tampon est assez grand, alors Strcpy est ok. Cependant, je préfère éviter Strcpy dans tous les cas. Les frais généraux sont si minuscules que vous êtes peu susceptibles de voir une réelle différence de performance.



1
votes

Il y a un problème avec ça. Tempsures pointera sur un bloc de mémoire de taille ininitialisée 1. Si vous souhaitez copier la chaîne des côtes en Tempsures, vous devrez également affecter une taille d'un octet plus longtemps, afin de maintenir le terminateur zéro pour la chaîne. La valeur renvoyée par SHLEN () n'inclut pas le terminateur zéro à la fin de la chaîne.


0 commentaires

1
votes

Non, pas vraiment. Comme d'autres l'ont déjà noté, vous devez attribuer de l'espace pour le terminateur Nul.

En outre, vous devez généralement pas jeter le retour du MALLOC . Il peut couvrir un bogue où vous avez oublié #include l'en-tête correct. Multiplier par Tailleof (Char) est également inutile, car les normes (C et C ++) définissent Tailleof (char) pour toujours être 1.

Enfin, chaque appel à MALLOC devrait inclure un test du résultat. Je serra dans une fonction dans une fonction: xxx


0 commentaires

3
votes

Comme il a été souligné, vous avez manqué un espace alloué pour la terminaison Nul Chararacter. Mais je voulais aussi signaler quelques autres choses qui peuvent rendre votre code plus concis.

Par définition, Tailleof (Char) code> est toujours 1, vous pouvez donc raccourcir votre ligne d'allocation à: P>

tempSides = strdup(inSides);


0 commentaires

9
votes

Notez que:

  1. Les chaînes sont terminées de zéro (\ 0) et SHLEN () ne le comptent pas;
  2. Par définition, Tailleof (Char) est 1 (octet), donc ce n'est pas nécessaire;
  3. Si vous utilisez un compilateur C (non C ++), il n'est pas nécessaire de le jeter à Char * ;

    afin que ce soit: xxx

    toujours, si vous voulez dupliquer le contenu de INSIESIDE , vous pouvez utiliser STRUP , par exemple: xxx


0 commentaires

0
votes

multiplier le nombre d'éléments par Tailleof (Char) est une question de préférence personnelle, car Tailleof (Char) est toujours 1. Toutefois, si vous le faites pour la cohérence , mieux utiliser le type de pointeur du destinataire pour déterminer la taille de l'élément, au lieu de spécifier de type explicitement. Et ne jetez pas le résultat de MALLOC xxx

bien sûr, lorsque vous travaillez avec des chaînes à terminaison zéro, vous devez vous rappeler d'allouer de l'espace supplémentaire pour le caractère zéro terminateur . Il n'ya aucun moyen de dire si votre intention de faire Tempsides une chaîne terminée zéro dans ce cas, je ne peux donc pas dire si vous en avez besoin.


2 commentaires

Certainement pas? Il est préférable d'utiliser des chaînes à terminaison zéro lors de l'appelant SHLEN ... S'il utilise sa propre chaleur, je ne veux vraiment pas être le programmateur de maintenance après lui. ;)


@Secure: cela signifie que si INSIDE est terminé de zéro. Il n'y a aucune indication dans le code que Tempsides devrait également être terminé de zéro.



0
votes

La bonne façon de répartition de la mémoire dynamique à Tempsides code> est indiquée ci-dessous:

tempSides = NULL;


0 commentaires