Visual Studio/C 기초

C언어 memset(), memcpy(), memmove()

낙락장송s 2013. 9. 13. 18:08

이번에는 메모리 블록을 다루는 방법을 구체적으로 포스팅하겠습니다.

지금까지 메모리의 블록을 할당하고 해제하는 방법을 살펴 보았습니다.

먼저, 메모리의 블록에서 모든 바이트를 특정 값으로 설정하기 위해서 memset() 함수를 사용합니다.

void *memset(void *dest, int c, size_t count); 

인수 dest는 메모리 블록을 가리킵니다. c는 설정할 값이고 count는 dest에서 시작하는 대상 메모리 블록의 바이트 수입니다.

c는 int형이지만 char형으로 취급이 됩니다. 즉, 하위 바이트만이 사용되므로 0부터 255까지의 c값을 지정할 수 있습니다.

 

다음은 memcpy() 함수인데요, 이 함수는 가끔 버퍼라고 하는 메모리 블록간에 데이터의 바이트를 복사합니다. 이 함수는 복사되는 데이터 형에 대해 신경 쓰지 않습니다.

 void *memcpy(void *dest, void *src, size_t count);

인수 dest와 src는 각각 대상과 원본 메모리 블록을 가리킵니다. count는 복사할 바이트 수를 지정합니다. 반환값은 dest고, 만약 메모리의 두 블록이 겹치는 함수는 정상적으로 동작하지 않을 것입니다.

src의 일부 데이터는 복사되기 전에 겹처질 수 있습니다.

이 상황을 해결하기 위해 memmove() 함수를 사용합니다. 이 함수는 한 메모리 블록에서 다른 곳으로 일정량의 바이트를 복사하므로 memcpy() 함수와 매우 비슷합니다. 그러나 이 함수는 메모리 블록이 겹치는경우를 적절히 다루므로 훨씬 더 유용합니다.

memmove() 함수는 블록을 덮어쓰게 되는 상황을 다룰 수 있으면서 memcpy()와 똑같은 기능을 갖추고 있습니다.

 void *memmove(void *dest, void *src, size_t count);

dest와 src는 대상과 원본 메모리 블록을 가리키고 count는 복사할 바이트 수를 지정합니다. 반환 값은 dest입니다.

만약 블록이 겹치면 함수는 겹치는 영역의 원본 데이터를 덮어쓰기 전에 정확히 복사해둡니다.

이제 예제를 보겠습니다.

 

#include <stdio.h>
#include <string.h>

char message1[60] = "no pains, no gains.";
char message2[60] = "abcdefghijklmnopqrstuvwxyz";
char temp[60];

main()
{
 printf("memset() 사용 이전의 message1[] :\t%s\n", message1);
 memset(message1+5,'@',10);
 printf("memset() 사용 이후의 message1[] :\t%s\n", message1);

 strcpy(temp, message2);
 printf("원본 메시지 : %s\n", temp);
 memcpy(temp+4, temp+16, 10);
 printf("오버랩 없이 memcpy() 사용 이전 : \t%s\n", temp);
 strcpy(temp, message2);
 memcpy(temp+6, temp+4, 10);
 printf("오버랩을 포함한 memcpy() 사용 이후 : \t%s\n", temp);

 strcpy(temp, message2);
 printf("원본 메시지 : %s\n", temp);
 memmove(temp+4, temp+16, 10);
 printf("오버랩 없이 memmove() 사용 이전 : \t%s\n", temp);
 strcpy(temp, message2);
 memmove(temp+6, temp+4, 10);
 printf("오버랩을 포함한 memmove() 사용 이후 : \t%s\n", temp);