memset memcpy memcpy_s [정리] C


C 함수의 기본이니 한번 정리 하고 넘어가는것도 좋을듯하여 정리해본다

출처 http://blog.naver.com/marine1959?Redirect=Log&logNo=150028864646

     http://www.devpia.com/Forum/BoardView.aspx?  no=155722&ref=155692&page=5&forumname=VC_QA&stype=&KeyW=memset+%bb%e7%bf%eb%c7%cf%b4%c2+%c0%cc%c0%af&KeyR=titlecontent

 

 

memcpy [메모리를 복사합니다]

 

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

 

Return Value

성공 - 복사된 메모리 주소(dest 매개변수) 반환

실패 - 없음

 

parameters

dest - 덮어쓸 메모리의 주소(목표, destination)

src - 읽어올 메모리의 주소(원본, Source)

count - 복사할 바이트의 크기

 

=============================================================================================

memcpy()는 지정한 크기만큼 메모리를 목사합니다 메모리의 어떤 영역을 얼마나 복사할지 알려주면 해당 영역에 어떤자료형이 잇던 상관없이 복사합니다

이와같이 모든 자료형을 처리하기위해 단위는 바이트를 사용합니다

10개 요소를 갖는 int배열을 복사하려면 10이아니라 배열전체의 크기인 40을 전달합니다. 60바이트 크기인 구조체를 20개 저장한 배열이라면

1200(60*20)바이트를 전달합니다

 

다음 코드는 memcpy()를 사용하는 방법을 보여줍니다. 요소의 크기를 알려주는 sizeof(int)를 쓰고 잇습니다

이와같이 해야 배열전체 크기를 전달할수 있습니다

 

int dest[10], src[10]={1,2,3,4,5,6,7,8,9,0};

memcpy(dest, src, 10*sizeof(int));

 

memcpy()를 사용할때의 주의 사항으로는  "중첩된 메모리 영역"이 있습니다 원본 버퍼와 목표버퍼의 메모리가 겹치면 결과를

정의 할수없다고 합니다.

 C언어 표준에는 이와같이 설명되어잇지만 VC++컴파일러에서는 표준과 상관없이 중첩된 메모리 영역을 제대로 처리합니다

memmove()는 중첩 메모리를 전문적으로 처리합니다 중첩되지않은 경우엔 memcpy(), 중첩된경우엔 memmove()로 역할을 분담했지만

현재에 와서는 두 함수 모두 똑같은 기능을 갖는것으로 보여줍니다

그러나 표준에 명기되어잇는것처럼 같은 배열 안에서 작업 할때는 memmove()를 사용하는것이 좋겟습니다.

 

메모리(문자열)를 복사하는 함수에는 memcpy(), memmove(), strcpy(), strncpy()가 잇습니다

이를 비교하는 표는 msdn에서 strcpy()를 검색하시면 정확히 나와잇습니다

 

 

참고로 C언어 표준에는 memory.h파일이없습니다 memcpy()와 strcpy()와같은 문자열과 메모리 관련 함수들은 모두 string.h파일에

있습니다 VC++6.0에서는 memory.h파일을 제공하고잇지만 표준이 아니므로 항상 string.h파일을 사용하길 바랍니다

 

 

memcpy_s : 보안성이 강화된 memcpy 확장함수

=> Copies bytes between buffers. These are version of memcpy, wmemcpy with security enhancements

     as described in Security Enhancements in the CRT

 

errno_t memcpy_s(
   void *dest,
   size_t numberOfElements,
   const void *src,
   size_t count
);
errno_t wmemcpy_s(
   wchar_t *dest,
   size_t numberOfElements,
   const wchar_t *src,
   size_t count
);

 

Parameters 

dest  : New buffer.

numberOfElements  : Size of the destination buffer.

src : Buffer to copy from.

count : Number of characters to copy.

 

 

memset

=> 이해하기 쉽게 memset(포인터, 값, 바이트수) 포인터가 가르카는 주소에서부터 바이트수만큼의 길이를 '값'으로 초기화 시키는 것입니다

char a[] = "abcdefg"

memset(a, 0, sizeof(a));

 

원형 : void *memset(void *src, int c, size_t n)

        src : 채울대상의 메모리

            c: 채울값, int 형이지만 1바이트(char)로 인식

            n: 채울갯수

헤더파일 : mem.h

기능: s가 포인트 하는 메모리값을 c로 n개 채운다.

memset 과 memcpy를 같이 쓰는 이유는 사용하기전에 사용할 부분을 깨끗하게 지우는 것이 필요하기 때문입니다

그냥 한다는 표현은 그렇지만 변수를 사용하기전에 깨끗하게 지우는것이 좋다는 사람을  많이 보았습니다 기본적으로 메모리를 할당받거나 하면

Debug에서 "0XCD" or "0XCC" 로 Release 에서는 Gabage값이 그대로 남아 있게 됩니다

 

또다른 이유는 memcpy 를 할때는 Terminate String인 0X00이 복사 되지 않습니다

즉, memcpy로 문자열을 복사하여 그대로사용하면 0X00까지 복사하는 함수를 사용할때 해당변수의 범위를 넘어서서 에러를 발생시킬수

있습니다

memset를 이용하여 미리 0X00으로 설정해두면 memcpy의 원본이 사본의 영역을 넘어서지 않는한 안전 합니다

 

다시한번 설명하면 위에서

memcpy(g_ClientID, tempID, strlen(tempID));

memset 없이 사용할경우 tempID 를 "Guest"라고 하고 g_ClientID의 길이를 32라고 할때, g_ClientID 역역에는 어떤값이

잇을지 알수가 없습니다 

그래서 g_ClientID에 "Guest"가 복사되고 난 다음 바이트에 0X00없는 경우가 생길수 있습니다  이때 그 다음 명령인

temp(CString형)에 g_ClientID을 넣을때 0X00를 넣을때 0X00를 g_ClientID 의 크기인 32바이트에서 찾지 못하면

계속 수Mbyte라도 복사하려 시도할수 잇으며  이때 다른 부분의 메모리를 건드려서 Access Violation 를 발생 시킬수 있습니다

 

참고로, memset과 memcpy를 그냥 사용하면 memcpy에서 g_ClientID의 범위를 넘어설 수 있습니다. 물론 잘 정의하여 그 크기를 넘지 않게 하면 됩니다. 하지만 그렇지 못할때를 대비해서 memcpy에서 strlen이 아닌 g_ClientID의 최대값을 넣어줍니다. 그러면 memcpy에서 g_ClientID의 범위를 넘어서 에러를 발생시키지는 않습니다. 그리고 반드시 memcpy후에는 맨뒤에 0x00를 넣어서 나중에 사용할때 에러가 생기지 않도록 해야합니다.

  char g_ClientID[32];
         ...
  memset( g_ClientID, 0x00, sizeof g_ClientID );
  memcpy( g_ClientID, tempID, sizeof g_ClientID );
  g_ClientID[31] = 0x00;

 

이렇게 해주시면 보다 안전하게 처리 될수 잇습니다

'Module > WindowsMFC' 카테고리의 다른 글

MFC Dlg 모달리스로 띄우기  (0) 2008.10.16
atoi() _wtoi() 문자열안에서 "문자열"검색!  (0) 2008.10.07
wchar -->> char ... 기타 등등..  (0) 2008.10.07
WCHAR 를 CHAR 로 바꾸기...  (0) 2008.10.07
recv() WCHAR 로 받을때  (0) 2008.10.07

댓글

Designed by JB FACTORY