Tout d'abord, quand vous faites:
num = "123056";
Vous ne copiez pas la chaîne « 123056 » dans la zone de tas alloué par malloc()
. En C, l'affectation d'un pointeur char *
une valeur de chaîne littérale équivaut à la définir comme une constante - à savoir identique à:
char str[] = "123056";
Alors, ce que vous venez accompli là, vous avez abandonné est votre seule référence à la Zone de segment de mémoire de 100 octets allouée par malloc()
, ce qui explique pourquoi le code suivant n'imprime pas la valeur correcte; 'p
' pointe toujours vers la zone de tas allouée par malloc()
(depuis num
pointé vers lui au moment de l'affectation), mais num
ne le fait plus.
Je suppose que vous avez réellement l'intention de faire était de copier la chaîne "123056" dans cette zone de tas. Voici comment faire:
strcpy(num, "123056");
Bien, cela est une meilleure pratique pour diverses raisons:
strncpy(num, "123056", 100 - 1); /* leave room for \0 (null) terminator */
Si vous venez faire:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char *num = malloc(100);
char *p = num;
strncpy(num, "123056", 100 - 1);
p = p + 3;
*p = '4';
printf("%s\n", num);
return 0;
}
Vous auriez obtenu la résultat correct:
123456
Vous pouvez contracter cette opération:
p = p + 3;
*p = '4';
... et éviter itérer le pointeur, par deferencing comme suit:
*(p + 3) = '4';
Quelques autres notes:
Bien que stylistique commune En pratique, la valeur de retour de malloc()
à (char *)
est inutile. La conversion et l'alignement du type void *
sont garantis par le langage C. TOUJOURS vérifier la valeur de retour malloc()
Il sera NULL si l'allocation de tas a échoué (c'est-à-dire que vous n'avez plus de mémoire), et à ce stade, votre programme devrait quitter.
En fonction de la mise en œuvre, la zone de mémoire allouée par malloc()
peut contenir des déchets obsolètes dans certaines situations.Il est toujours une bonne idée de zéro dehors après attribution:
memset(num, 0, 100);
Ne jamais oublier de free()
votre tas! Dans ce cas, le programme va quitter et le système d'exploitation va nettoyer vos déchets, mais si vous ne prenez pas l'habitude, vous aurez des fuites de mémoire en un rien de temps.
Alors, voici la version "meilleures pratiques":
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
char *num, *p;
/*
* Don't take 1-byte chars for granted - good habit to get into.
*/
num = malloc(sizeof(char) * 100);
if(num == NULL)
exit(1);
memset(num, 0, sizeof(char) * 100);
p = num;
strncpy(num, "123056", 100 - 1);
*(p + 3) = '4';
printf("%s\n", num);
free(num);
return 0;
}
double possible de [Pourquoi est-ce que je reçois une erreur de segmentation lors de l'écriture à une chaîne initialisée avec "char \ * s" mais pas "char s \ [\]"? ] (http://stackoverflow.com/questions/164194/why-do-i-get-a-segmentation-fault-when-writing-to-a-string-initialized-with-cha) – jww