まず、:
num = "123056";
あなたはmalloc()
によって割り当てられたヒープ領域に文字列「123056」をコピーしていません。 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
この操作を契約することができ、次のようdeferencingにより、
p = p + 3;
*p = '4';
...とポインタを反復避ける:
*(p + 3) = '4';
他のいくつかの注意事項:一般的な文体が、
実際には、malloc()
の戻り値を(char *)
にキャストする必要はありません。 void *
タイプの変換とアラインメントは、C言語によって保証されています。
いつも戻り値malloc()
をチェックしてください。ヒープの割り当てに失敗した場合(つまりメモリ不足の場合)はNULLになり、その時点でプログラムは終了します。
実装によっては、malloc()
によって割り当てられるメモリ領域に特定の状況で古いゴミが含まれることがあります。
memset(num, 0, 100);
がfree()
あなたのヒープに決して忘れない:常に割り当てた後、それをゼロにすることをお勧めします!この場合、プログラムは終了し、OSはゴミをクリーンアップしますが、慣れていなければ、すぐにメモリリークが発生します。
ので、ここでは、 "ベストプラクティス" バージョンです:
#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;
}
可能な重複「のchar \ * s」のではなく、「文字の\ [\]」で初期化された文字列への書き込み時に[なぜ私がセグメンテーションフォールトを得るのですか? ](http://stackoverflow.com/questions/164194/why-do-i-get-a-segmentation-fault-when-writing-to-a-string-initialized-with-cha) – jww