単純に0埋めをしたいのであれば、他の皆さんが示すとおり、NULL
ではなく単純に0
または'\0'
を使うべきです。ですが、それ以外でも問題があるコードになっていますので、そこについて述べさせていただきます。(つまり、ただの蛇足です)
###ほとんどの環境においてNULL
は((void *)0)
であり、整数値の0
と同じとは限りません。
C言語では0
というリテラルがポインタとして解釈されるときはヌルポインタとすると定義されています。ヌルポインタは値が0のポインタという意味では無く、どこもさしていないことが保証されたポインタという意味です。そして、マクロ定数NULL
が先ほどのヌルポインタになるようにマクロを定義するとしています。そのため、gccではNULL
は((void *)0)
としています(あくまでgccの場合であり、他のコンパイラも同じであるという保証はありません)。
注意すべきはヌルポインタはリテラルが0
なだけで、実際のデータが全て0であるとは限らないと言うことです。(int)NULL
つまり(int)((void *)0)
が、(int)0
と同じになる保証はありません。
そして、今回は、memsetがバイト単位で書き込むと言うことがもっと意味不明なコードにしてしまっています。もし、NULL
のメモリ上の実際のデータが[0x12 0x34 0x56 0x78]なら、リトルエンディアンの環境では[0x12 0x12 0x12 0x12]と書き込まれていくことになります。これはきっと、期待している動作では決して無いでしょう。
つまり、ヌルポインタで埋めたいという状況であっても、memsetの第2引数にNULL
を使うこと自体が間違っています。
※ NULLの読み方にはナル派(英語かぶれ)とヌル派(独語かぶれ)の二つの派閥があります。
※ NULL
とは違い'\0'
は実際のメモリ上のデータが0であることを表しています。
参考:
[迷信] とりあえず memset で初期化 | 株式会社きじねこ
C言語の基礎知識(?)メモ(Hishidama's C Memo)#NULL
###void *
型をキャストするときはintptr_t
またはuintptr_t
を使うべきです。
void *
のサイズがlong
で収まるという保証はありません(事実、Windowsのx86_64環境では収まりません)。int
で足りないから安直にlong
としてはいけません。ポインタのサイズが必ず収まるという整数型としてintptr_t
とuintptr_t
が用意されています。ポインタを整数として扱いたい場合は、こちらを使うべきです。
※ intptr_t
等が使えないC90で書く必要がある場合は、プリプロセッサで分岐するなどの工夫をする必要があります。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/06/07 11:51
2016/06/07 21:41 編集
2016/06/07 23:08
2016/06/08 05:24