
■1.strNcmpとmemcmpが違う例
#include <stdio.h>
#include <string.h>
char s1[] = "abc\0DEF" ; //abc+DEF
char s2[] = "abc\0XYZ" ; //abc+XYZ
int main(void){
if(strncmp(s1,s2,sizeof(s1)) == 0)
printf("strncmpは'¥0'を終端とする:%sと%sは同じ\n",&s1[0],&s2[0]);
if(memcmp(s1,s2,sizeof(s1)) != 0)
printf("memcmpは'¥0'を終端としない:%sと%sは違う\n",&s1[4],&s2[4]);
}
●違いその1
strncmp()は終端文字¥0までしか比較しない
memcmp()は終端文字¥0を超えて比較する。
●違いその2
strncmp()の第1,第2引数には char * 型しか渡せません。
(キャストしてコンパイラを騙し警告を無視するのは論外とします)
memcmp()の第1,第2引数はvoid *型なのでデータのアドレスならば
何でも渡せます。
●実行結果
strncmpは'¥0'を終端とする:abcとabcは同じ
memcmpは'¥0'を終端としない:DEFとXYZは違う

■2.strNcpyとmemcpyが違う例
//gcc -g f1.c -fsanitize=address
#include <stdio.h>
#include <string.h>
static char コピー元小[8] = "abc\0xyz";
static char コピー先大[16];
int main(void){
//'\0'を終端とするstr系
strncpy(コピー先大,コピー元小,sizeof(コピー先大));
printf("%s:%s\n",&コピー先大[0],&コピー先大[4]);
//'\0'を終端としないmem系(バグあり)
memcpy(コピー先大,コピー元小,sizeof(コピー先大));//★
printf("%s:%s\n",&コピー先大[0],&コピー先大[4]);
}
●違いその1
strncpy()は終端文字¥0までしか転送しません。
memcpy()は終端文字¥0を超えて指定のサイズまで転送します。
●違いその2
第2引数が第3引数より短い場合、
strncpy()は残りを¥0で埋めます。
memcpy()は第2引数で領域外参照が発生して動作不明となります。
※このプログラムの例では転送元は8byteしかないのに16byte読み込むので領域外参照のバグとなります。
gcc -g -fsanitize=address でコンパイルすると異常終了しました。
参考:
C-FAQ 13.2:任意のバイトをコピーするときには、普通は memcpy()のほうがstrncpy()よりも適切なルーチンである。
http://www.kouno.jp/home/c_faq/c13.html#2