C/400

59. mem と str のちがいの注意

良く似た関数として strcpy と memcpy や strncmp と memcmp がある。

strxxx 関数は文字どおりストリング、つまり NULL-STOP の文字列を対象として処理する
関数であり、memxxx 関数はすべての文字列を対象としていることに違いがある。

日常的には strxxx を使用する機会が圧倒的に多いので、無意識に strxxx 関数を優先して
使用するが

unsigned char BINARY[]  = {0x00, 0x00};
unsigned char FLOAT[]   = {0x00, 0x01};
unsigned char ZONED[]   = {0x00, 0x02};
unsigned char PACKED[]  = {0x00, 0x03};

    :

if(strncmp(fldtype, BINARY, 2) == 0 ||          
   strncmp(fldtype, FLOAT, 2) == 0 ||           
   strncmp(fldtype, ZONED, 2) == 0 ||           
   strncmp(fldtype, PACKED, 2) == 0){/* 数字 */ 
        :

のような演算はコンパイルは成功するが実行では正しく動作しない。
なぜなら char 変数 : BINARY, FLOAT, ZONED, PACKED のいずれもが
0x00 つまり NULL 値から始まっているので strxxx 関数では NULL と比較していることに
なってしまうからである。0x00 以降の文字列は strxxx 関数によっては処理されない。
この例では正しくは memcmp を使用するべきである。

memcmp であれば先頭の文字が 0x00 であっても正しく指定したバイト数分だけの
比較演算が行われるからである。
このように strxxx 関数は思わぬ障害となる場合があるから注意が必要である。
strcpy と memcpy の場合も同様である。