Prima di tutto, quando si esegue:
num = "123056";
Non sta copiando la stringa "123056" per l'area di heap allocata da malloc()
. In C, l'assegnazione di un puntatore char *
un valore letterale di stringa equivale a impostare come una costante - cioè identico a:
char str[] = "123056";
Allora, che cosa hai appena compiuto c'è che hai abbandonato il tuo unico riferimento alla Area heap da 100 byte allocata da malloc()
, motivo per cui il codice successivo non stampa il valore corretto; 'p
' punta ancora all'area di heap allocata per malloc()
(dal momento che l'num
l'ha indicata al momento dell'assegnazione), ma non lo è più num
.
Presumo che in realtà si intendesse fare era copia la stringa "123056" in quell'area di heap. Ecco come fare:
strcpy(num, "123056");
Anche se, questo è meglio pratica per una serie di motivi:
strncpy(num, "123056", 100 - 1); /* leave room for \0 (null) terminator */
Se avessi appena fatto:
#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;
}
Si sarebbe ottenuto il risultato corretto:
123456
È possibile contrarre questa operazione:
p = p + 3;
*p = '4';
... e di evitare l'iterazione il puntatore, da deferencing come segue:
*(p + 3) = '4';
Poche altre note:
Sebbene stilistica comune pratica, la trasmissione del valore di ritorno di malloc()
a (char *)
non è necessaria. La conversione e l'allineamento del tipo void *
sono garantiti dal linguaggio C.
Controllare SEMPRE il valore di ritorno di malloc()
. Sarà NULL se l'allocazione dell'heap non è riuscita (ad esempio, hai esaurito la memoria) ea quel punto il tuo programma dovrebbe uscire.
A seconda dell'implementazione, l'area della memoria allocata da malloc()
può contenere rifiuti obsoleti in determinate situazioni.E 'sempre una buona idea a zero fuori dopo l'allocazione:
memset(num, 0, 100);
non dimenticare mai di free()
tuo mucchio! In questo caso, il programma uscirà e il sistema operativo ripulirà la tua spazzatura, ma se non prendi l'abitudine, avrai perdite di memoria in pochissimo tempo.
Quindi, ecco la versione "best practice":
#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;
}
Eventuali duplicati di [Perché ricevo un errore di segmentazione quando si scrive in una stringa inizializzata con "char \ * s" non ma "char s \ [\]"? ] (http://stackoverflow.com/questions/164194/why-do-i-get-a-segmentation-fault-when-writing-to-a-string-initialized-with-cha) – jww