[C언어] memcpy(),memmove(),strncpy() 함수의 차이점..
글쓴이: gyxor / 작성시간: 금, 2004/04/02 - 1:15오후
#include<stdio.h> #include<string.h> int main(){ char data1[100]="abcdefghijklmnopqrstuvwxyz"; char temp1[100]={0}; char temp2[100]={0}; char temp3[100]={0}; printf("original :\n %s\n",data1); strcpy(temp1,data1); memcpy(temp1+6,temp1+4,10); printf("memcpy result :\n %s\n",temp1); strcpy(temp2,data1); memmove(temp2+6,temp2+4,10); printf("memmove result:\n %s\n",temp2); strcpy(temp3,data1); strncpy(temp3+6,temp3+4,10); printf("strncpy result:\n %s\n",temp3); return 0; }
: 결과 :
original :
abcdefghijklmnopqrstuvwxyz
memcpy result:
abcdefefghijklmnqrstuvwxyz
memmove result:
abcdefefghijklmnqrstuvwxyz
strncpy result:
abcdefefghghklklqrstuvwxyz
Press any key to continue
가 나옵니다.
그런데..
memcpy의 결과는 예상한바에 의하면
memcpy result:
abcdefefefefefefqrstuvwxyz
가 나와야 한다고 생각했습니다.
주소가 겹칠경우 overlap 여부가
memcpy와 memmove의 차이점으로 알고있었습니다.
(책에도 예제에는 그렇게 나와있구요..)
첫째,
그렇다면
memcpy와 memmove 두 함수의 차이점이 무엇인지 알려주시면 감사하겠습니다.
둘째,
strncpy의 경우엔 overlap을 이상하게 처리하는데요..
복사할부분을 임시저장하는 공간이 2byte여서 그런가요?
두가지 답변부탁드립니다.
Forums:
memmove , memcpy
memcpy와 memmove의 차이는 copy 시에 별도의 버퍼를 사용하느냐 입니다.
memcpy는 별도의 buffer를 사용하지 않기때문에
overlab 된 부분을 다룰경우에
behavior is "undefined" 입니다.
Re: memmove , memcpy
그렇다면.. 더더욱
memcpy result:
abcdefefefefefefqrstuvwxyz
가 되어야 할거 같은데요..
Undefined로 이해하고 넘어가겠습니다.
답변감사합니다~!!
Undefined이기 때문에 시스템에 따라 다른 결과가 나올 수 있다는
Undefined이기 때문에 시스템에 따라 다른 결과가 나올 수 있다는 것이지요.
FreeBSD의 경우는 man 페이지에 bcopy()를 이용하기 때문에 오버랩이 가능하다는 부연 설명이 있네요. 표준 라이브러리의 소스를 살펴보는것도 괜찮을듯 싶습니다.
C의 이식성을 살리려면 표준대로 작성하는게 옳겠지요.
Re: memmove , memcpy
제가 소스코드를 확인해 본건 아니지만...
제가 만들었다고 생각해보면 중간 버퍼를 사용하진 않았을꺼고... memmove 제작자도 마찮가지 였을꺼라 생각합니다.
memcpy는 메모리의 특정 부분의 원하는 크기를 다른 곳으로 복사하는 기능입니다.
memmove도 memcpy와 같은 기능을 하지만 복사되는 영역이 겹쳐지더라도 괜찮습니다.
아마 겹쳐지는 부분이 있으니까 중간 버퍼를 사용해서 해결해야 한다고 생각하셨겠지만... 복사되기 시작하는 위치를 조정해서도 가능합니다.
Re: memmove , memcpy
답변 달아놓고 보니까.. 너무 대충 써놓은 것 같아서 예를 들어보겠습니다.
10번지의 10개의 데이터를 15번지로 이동할때...
memcpy의 방법은 10번지를 15번지로 옮기고 11번지를 16번지로 옮기고...
식으로 진행하니까.. 15번지부터 19번지의 값이 문제가 됩니다.
이문제를 풀려면 19번지를 23번지로 옮기고, 18번지를 22번지로 옮기고...
식으로 뒷쪽부터 거꾸로 진행하면 됩니다.
제가 memmove의 소스 코드를 본적은 없지만 이런식으로 할꺼라 생각합니다.
왜냐면.. 제가 초딩때 MSX라는 컴퓨터에서 Z-80 어셈블러를 처음 배워 사용했었는데.. 그때 제가 본 책에 나와있었던 내용입니다.
맞습니다.
아 맞습니다.. 제가 사용하는 hp의 man page에 임시 버퍼를 사용한다고
되어있어서 무심코 그렇게 말했습니다만.
임시 버퍼를 사용하는 것은 일종의 방편이 맞구요.
꼭 사용할 필요는 없다는 님의 말씀에 동의합니다.
.
복사방향을 바꾸게 되면 버퍼가 필요없군요~
답변감사합니다.
그런데..이것저것 해본결과 외부적으로..
memcpy 와 memmove는 차이점을 찾을수가 없었습니다.
ps : 처음에..
copy하면 복사가 되고 move하면 복사후 원래 값이 사라질줄 알았습니다.
물론내부적으로 memmove는 버퍼를 사용하니까 그것이 차이가 되겠군요..
구현을 어떻게
구현을 어떻게 했냐의 문제가 아니고 표준스펙을 준수하는냐의 문제입니다.
특정 std c lib. 에서만 프로그램을 작동 시킬게 아니라면 항상 표준의 범위에서 코딩을 해야 합니다.
즉, 내 시스템에서는 memcpy 가 overlap 된 메모리도 잘 복사한다고 해서, memcpy 를 이용해서 overlap 된 메모리를 복사하면 안된다는 것이지요.
예를 들어, linux 에서는 잘 작동 할 수도 있지만, windows 에서는 안될 수도 있습니다.
하지만 memmove 를 사용한다면 두 머신에서 잘 작동할 것입니다. 이것이 바로 표준 스펙입니다.
반대로, 특정 시스템에서 memmove 가 memcpy 와 비슷한 성능을 보인다고, 다른 시스템에서도 그럴것이라고 가정 할 수 없습니다.
표준 스펙은 내부 구현까지 제약하는 경우는 거의 없습니다.
대표적으로 malloc 함수는 solaris 와 linux 에서 동작이 동일합니다.
하지만, 내부 구현은 서로 매우 상이해서 매우 다른게 동작합니다.
다만, 표준 스펙 범위 내에서는 두 함수가 동일하게 작동할 뿐입니다.
댓글 달기