[C]memcmp
memcmp함수는 두문자열을 바이트단위로 비교하는 함수입니다.
1️⃣ 함수원형
< memset >
void *memcmp(const void *str1, const void *str2, size_t size)
2️⃣ 헤더파일, 반환값
반환값:
조건 반환값(size_t) str1 > str2 1 or 양수 str1 == str2 0 str1 < str2 -1 or 음수 헤더파일: <string.h>
3️⃣ 함수구현
< memcmp >
int memcmp(const void *str1, const void *str2, size_t size)
{
const unsigned char *s1;
const unsigned char *s2;
s1 = str1;
s2 = str2;
while (size-- > 0)
{
if (*s1 != *s2)
return (*s1 - *s2);
s1++;
s2++;
}
return (0);
}
4️⃣ 특징 & 주의사항
- size의 값이 음수가 되면 버퍼오버플로우(size_t는 unsigned형으로 선언되어 있기 때문)가 일어납니다. 컴파일러에 따라서 경고메시지를 출력해주기도 합니다. 하지만 대부분의 컴파일러에서 오버플로우난 상태로 함수가 실행됩니다.
- 바이트단위로 비교를 하기 때문에 255를 초과하는 int형정수를 사용할 경우 예상치 못한 결과를 얻게됩니다.(리틀 엔디언일 경우)
- void형으로 인자를 받고 바이트단위로 비교하기 때문에 이차원 배열도 비교가 가능합니다.
5️⃣ 코드예시(특이케이스)
1. < 255를 초과하는 int형정수를 사용할 경우(특징2) >
#include <stdio.h>
#include <string.h>
int main(void)
{
int num1[] = {1, 2, 3, 5};
int num2[] = {1, 2, 3, 256};
printf("%d\n", memcmp(num1, num2, 4*sizeof(int)));
}
/* ---결과--- */
5(리눅스), 1(윈도우)
- 기대값:
-256(리눅스), -1(윈도우)
- 출력값:
5(리눅스), 1(윈도우)
- 원인: 바이트단위로 검사
이유: 4번째 원소에서 차이가나는데 리틀엔디언 기준으로 메모리를 살펴보면 ‘(int)5’는
05 00 00 00
‘(int)256’은00 01 00 00
으로 스텍에 쌓여있기 때문에 앞의 1바이트 부분만 검사하고 결과를 출력하게 됩니다.- 결론: 1byte단위로 값을 비교하는 형식이기 때문에 리틀엔디언 환경에서는 1byte의 크기가아닌 자료형을 사용하면 예상치 못한 결과가 생길 수 있습니다.
빅엔디언
환경에서는 int형 범위내의 모든정수가 비교가능하지만리틀엔디언
환경에서는 255이하의 int형정수만 사용하는 것이 좋습니다.
2. < 2차원배열을 비교할 경우(특징3) >
(1)char형 2차원 배열
int mainv(void)
{
char word1[2][5] = {"same", "abcd"};
char word2[2][5] = {"same", "abcb"};
printf("%d\n", memcmp(word1, word2, sizeof(word1)));
}
/*---출력---*/
1(윈도우), 2(리눅)
(2)int형 2차원 배열
int main(void)
{
int ss[2][5] = { {1, 2, 3, 4} , {1, 2, 3, 4} };
int ss2[2][5] = { {1, 2, 3, 4} , {1, 2, 3, 7} };
printf("%d\n", memcmp(ss, ss2, sizeof(ss)));
}
/*---출력---*/
-1(윈도우), -3(리눅스)
(3)포인트 배열
int main(void)
{
int num1[] = {1, 2, 3, 5}; //num2보다 큰주소에 위치
int num2[] = {1, 2, 3, 6}; //num1보다 작은주소 위치
int *ss[1];
int *ss2[1];
ss[0] = num1;
ss2[0] = num2;
printf("%d\n", memcmp(ss, ss2, sizeof(ss)));
}
/*---출력---*/
1(윈도우), 16(리눅스)
/*---num1, num2주소---*/
// num1의 주소가 num2의 주소보다 16(int형원소 4개)만큼 큽니다.
- 위의 3가지 케이스처럼 2차원배열도 memcmp함수로 비교가 가능합니다. 하지만 정확한 비교를 위해서는 두배열의 메모리가 형태가 같은 것이 좋습니다.