C/C++/프로그래밍 일반
memset, memcpy, memmove, memcmp 멤형제들
Midach
2010. 4. 29. 20:58
선행 학습이 필요합니다.
http://ekessy.tistory.com/10 C/C++에서의 일반변수, 포인터변수, 메모리에 대해
memset, memcpy, memmove, memcmp등은 메모리 관련 함수들이다.
각각 메모리를 특정정수값으로 초기화하고, 메모리를 복사하고, 이동시키고, 비교하는 함수가 되겠다.
memset
void * __cdecl memset(_Out_opt_bytecapcount_(_Size) void * _Dst, _In_ int _Val, _In_ size_t _Size)
void* _Dst // 초기화할 시작 주소
int _Val // 초기화할 값
size_t _Size // 대상의 크기
리턴 //_Dst의 시작주소
void* _Dst // 초기화할 시작 주소
int _Val // 초기화할 값
size_t _Size // 대상의 크기
리턴 //_Dst의 시작주소
memset은 지정된 수를 1바이트단위로 지정된 주소부터 지정된 크기까지 채워주는 함수이다.
예를 들어
int n;
memset( &n, 10, sizeof(int) );
이렇다면 n에 0x0a0a0a0a에 들어가게된다.
1바이트단위라고 했는데, 1바이트가 넘어선 수를 넣으면 어떻게 될까?
int n;
memset( &n, 321, sizeof(int) );
이렇다면 n에 0x41414141이 들어가게 된다. (321이 16진수로 141이다.)
memcpy
void * __cdecl memcpy(_Out_opt_bytecapcount_(_Size) void * _Dst, _In_opt_bytecount_(_Size) const void * _Src, _In_ size_t _Size)
void* _Dst // 복사될 대상의 시작 주소
const void* _Src // 복사할 소스의 시작주소
size_t _Size // 복사되는 총 바이트 수(복사할 소스의 시작주소부터 + 바이트수가 복사됨)
리턴 //_Dst의 시작주소
void* _Dst // 복사될 대상의 시작 주소
const void* _Src // 복사할 소스의 시작주소
size_t _Size // 복사되는 총 바이트 수(복사할 소스의 시작주소부터 + 바이트수가 복사됨)
리턴 //_Dst의 시작주소
memcpy는 지정된 주소부터 지정된 크기까지 복사하여 복사될 주소부터 붙여넣기(?)하는 함수이다. 물론 메모리내부의 값을 복사시켜준다.
// dest에 321이 복사된다.
int n = 321;
int dest;
memcpy( &dest, &n, sizeof(int) );
// dest에 0xcccccc41이 복사된다. dest를 먼저 초기화를 안했기 때문이다.
int n = 321;
int dest;
memcpy( &dest, &n, sizeof(char) );
// dest에 0x00000041이 복사된다.(10진수로 65)
int n = 321;
int dest = 0;
memcpy( &dest, &n, sizeof(char) );
// dest에 안녕하세요. 가 복사된다.
char* str = "안녕하세요.";
char dest[128] = "";
memcpy( dest, str, strlen( str )+1 );
물론 구조체도 가능하고, 배열도 가능하다.
int arr[128] = { .......... };
int dest[128];
memcpy( dest, arr, sizeof( arr ) );
int* test[5];
int* dest[5];
memcpy( dest, test, sizeof( test ) );
memmove
void * __cdecl memmove(_Out_opt_bytecapcount_(_Size) void * _Dst, _In_opt_bytecount_(_Size) const void * _Src, _In_ size_t _Size);
void* _Dst // 이동될 대상의 시작 주소
const void* _Src // 이동할 소스의 시작주소
size_t _Size // 이동되는 총 바이트 수(복사할 소스의 시작주소부터 + 바이트수가 복사됨)
리턴 //_Dst의 시작주소
void* _Dst // 이동될 대상의 시작 주소
const void* _Src // 이동할 소스의 시작주소
size_t _Size // 이동되는 총 바이트 수(복사할 소스의 시작주소부터 + 바이트수가 복사됨)
리턴 //_Dst의 시작주소
memcpy와 비슷하기 때문에 생략한다.
memcmp
int __cdecl memcmp(_In_opt_bytecount_(_Size) const void * _Buf1, _In_opt_bytecount_(_Size) const void * _Buf2, _In_ size_t _Size)
const void* _Buf1 // 비교할 대상1의 시작주소
const void* _Buf2 // 비교할 대상2의 시작주소
size_t _Size // 비교 크기
리턴 // _Buf1이 _Buf2보다 작은경우 0보다 작은값이 리턴, 같을경우 0이 리턴, _Buf1이 _Buf2보다 클경우 0보다 큰값이 리턴
const void* _Buf1 // 비교할 대상1의 시작주소
const void* _Buf2 // 비교할 대상2의 시작주소
size_t _Size // 비교 크기
리턴 // _Buf1이 _Buf2보다 작은경우 0보다 작은값이 리턴, 같을경우 0이 리턴, _Buf1이 _Buf2보다 클경우 0보다 큰값이 리턴
memcmp는 단순히 메모리의 값들을 비교해줍니다. 이를 응용하여 아래와 같이 문자열을 비교할 수도 있구요.
char* str1 = "안녕하세요?";
char* str2 = "안녕하세요?";
if( memcmp( str1, str2, strlen(str1)+1 ) == 0 )
{
printf("두 문자열이 같습니다." );
}
그냥 비교하는 것이 아닌, 당연한 얘기지만 범위를 지정할 수가 있는데요... 다음과 같은 처리가 가능합니다.
int n = 321; // 0x141
int n2 = 65; // 0x41
if( memcmp( &n, &n2, sizeof(char) ) == 0 )
{
printf("첫번째 바이트 부분의 값이 같습니다." );
}
char* str1 = "hoo ekessy";
char* str2 = "haha ekessy";
if( memcmp( &str1[4], &str2[5], strlen("ekessy")) == 0 )
{
printf("ekessy");
}