首先,當你這樣做:
num = "123056";
你沒有複製字符串「123056」堆由malloc()
分配的區域。在C語言中,分配char *
指針字符串文本值等同於設置它爲一個常數 - 即等同於:
char str[] = "123056";
所以,你剛剛完成有你放棄了你的唯一參考由malloc()
分配的100字節堆區域,這就是爲什麼您的後續代碼不能打印正確的值; 'p
'仍然指向由malloc()
分配的堆的區域(因爲num
在作業時指向它),但num
不再。
我假設你實際打算做的是將拷貝到的字符串「123056」到那個堆區。以下是如何做到這一點:
strcpy(num, "123056");
雖然,這是多種原因更好的做法:
strncpy(num, "123056", 100 - 1); /* leave room for \0 (null) terminator */
如果你剛剛做:
#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;
}
你會得到的正確的結果:
123456
您可以承攬此操作:
p = p + 3;
*p = '4';
...,避免迭代指針,通過deferencing如下:
*(p + 3) = '4';
其他一些注意事項:
雖然常見文體練習中,將malloc()
的返回值轉換爲(char *)
是不必要的。 C語言保證了void *
類型的轉換和對齊。
總是檢查返回值malloc()
。如果堆分配失敗(即你內存不足),那麼它將爲NULL,並且此時應該退出程序。
根據實施情況,在某些情況下,由malloc()
分配的內存區域可能包含陳舊垃圾。它始終是分配到零之後出來一個好主意:
memset(num, 0, 100);
千萬不要忘了你的free()
堆!在這種情況下,程序將退出並且操作系統會清理垃圾,但如果您沒有養成這種習慣,您很快就會發生內存泄漏。
所以,這裏的 「最佳實踐」 的版本:
#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;
}
的可能的複製[爲什麼寫有「字符\ * S」,而不是「char形式\ [\]」初始化字符串時,我得到一個分段錯誤? ](http://stackoverflow.com/questions/164194/why-do-i-get-a-segmentation-fault-when-writing-to-a-string-initialized-with-cha) – jww 2016-10-20 11:07:51