memcpy は、指定されたバイト数に従ってソース領域からデスティネーション領域へデータを非破壊的に複製する関数です。以下はその自作実装例です:
void* my_memcpy(void* dst, const void* src, size_t n) {
if (!dst || !src) return NULL;
unsigned char* d = (unsigned char*)dst;
const unsigned char* s = (const unsigned char*)src;
for (size_t i = 0; i < n; ++i) {
d[i] = s[i];
}
return dst;
}
この実装では、unsigned char* へのキャストにより1バイト単位のアクセスを可能にし、任意の型のデータを安全に転送できます。たとえば、int 配列5要素(20バイト)をコピーすると、元の値がそのまま転送されます。
memmove は、memcpy の拡張版であり、ソースとデスティネーション領域が重なる場合でも正しく動作します。重複領域へのコピーでは、方向性が重要です:
- デスティネーションがソースより前にある → 前方からコピー(上書きリスク回避)
- デスティネーションがソースより後にある → 後方からコピー(既存データ保護)
以下はその条件付き実装:
void* my_memmove(void* dst, const void* src, size_t n) {
if (!dst || !src || n == 0) return dst;
unsigned char* d = (unsigned char*)dst;
const unsigned char* s = (const unsigned char*)src;
if (d < s) {
// ソースがデスティネーションより後 → 前方から
for (size_t i = 0; i < n; ++i) {
d[i] = s[i];
}
} else {
// ソースがデスティネーションより前 → 後方から
for (size_t i = n; i > 0; --i) {
d[i-1] = s[i-1];
}
}
return dst;
}
memset は、指定アドレスから始まる n バイトを特定の値で初期化する関数です。たとえば、int arr[10] 全体(40バイト)をゼロで埋めるには:
memset(arr, 0, sizeof(arr));
第2引数は int ではなく unsigned char として解釈されるため、値は0〜255の範囲で指定します。
memcmp は、2つのメモリ領域をバイト単位で比較し、差分が発生した最初の位置の符号付きバイト値を返します。戻り値は:
< 0:左側が辞書順で小さい== 0:全バイトが一致> 0:左側が辞書順で大きい
int result = memcmp(ptr_a, ptr_b, 16); // 先頭16バイトを比較