Posts
memset はバイト単位で処理をする
memset は危険なヤツだった。例えば以下のような配列を初期化するコードを書いたとする。
#define SIZE 10 int nBuffer[SIZE]; // 配列を 0xff で初期化 memset( nBuffer, 0xff, sizeof( int ) * SIZE );
int は 4 バイトなので、
-0--1--2--3--4--5--6--7--8--9--A--B--C--D--E--F ff 00 00 00 ff 00 00 00 ff 00 00 00 ff 00 00 00
このように 4 バイト単位 (リトルエンディアンなので反転) で初期化されると思っていた。
コードのイメージとしては、
for ( int i = 0; i < SIZE; i++ ) { nBuffer[i] = 0xff; }
for 文と同等の処理を想定していたが実際は、
-0--1--2--3--4--5--6--7--8--9--A--B--C--D--E--F ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff
こうなっていた。よくよく考えてみたら memset の引数リストには項目当たりのサイズ指定が無い…。配列を 0 で初期化するときは、
memset( nBuffer, 0, sizeof( int ) * SIZE );
こんな書き方をよく使っていたので「memset = 配列初期化」というイメージがこびりついていた。
設定値をバイト単位に展開したとき、0xff だと 0xffffffff になってしまうが、0x00 なら 0x00000000 になるので問題がなかったというオチ。
標準関数の名前には一定の規則性があるので、chr が含まれているときは「文字を扱う関数だな」となるが、mem の場合は…と考えると、
名前 | 意味 |
---|---|
chr | 文字 |
str | 文字列 |
mem | 文字列 (終端なし) |
こんな命名規則になっていたりするのだろうか。