まず第一に、あなたがするとき:
num = "123056";
によって割り当てられたヒープの領域に文字列「123056」をコピーしていませんmalloc()
。Cでは、char *
ポインタに文字列リテラル値を割り当てることは、それを定数として設定することと同じです。つまり、次のようになります。
char str[] = "123056";
したがって、ここで達成したのは、によって割り当てられた100バイトのヒープ領域への唯一の参照を放棄したことです。malloc()
これが後続のコードが正しい値を出力しない理由です。' 'は、 (割り当て時にポイントされたため)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';
...そして、次のように延期することにより、ポインタの反復を避けます。
*(p + 3) = '4';
他のいくつかの注意:
malloc()
一般的なスタイルの慣習ですが、 toの戻り値をキャストする(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;
}