memcpy 에 관하여.

tombraid의 이미지

적당히 넓은 배열이 있습니다.

이 배열의 일부분을 쉬프트 하려고 할때, memcpy를 다음과 같이 써도 되나요?

memcpy (ptr + 1, ptr, size * count);

제가 생각하기에는 안될것 같은 느낌이 들어서요.

그렇다면, 쉽게 생각할 수 있는 방법이 count 만큼 뒤에서 부터 옮기는 방법이 있을꺼구요.

for (i = count; i > 0; i--) {
    memcpy (ptr + i, ptr + i - 1, size)
}

또 다른 방법으로는 특정 사이즈 만큼의 버퍼를 두고 옮기는 방법이 있을꺼 같은데요.

buf[bufsize];

for (i = count; i > 0; i -= bufsize) {
    memcpy (buf, ptr + i - 1, size * min(i, bufsize));
    memcpy (ptr + i, buf, size * min(i, bufsize));
}

대충드는 생각을 코드로 옮겨서 좀이상하긴 하지만, 머 대충 생각은 전달 되었을것 같습니다.

위의 방법이 두가지 방법이 옮기려는 size 혹은 count 등에 의해서 한쪽이 더 유리해 질것 같은데요.

어느 정도를 그 임계치로 보아야 할까요?

그리고, 위와 같은 일을 하기위해서 더 좋은 방법이 있으시면 가르쳐 주세요.

:P

ssehoony의 이미지

답은 안됩니다.

저렇게 메모리가 dest 와 src 가 겹치는 걸 man 페이지에서는 overlap 이라고 하더군요 ^^
overlap 되면 memcpy 를 사용하시면 안되구요. (man memcpy 에 보면 나와있습니다.) memmove 를 사용하세요.
아마 memmove 가 내부적으로 malloc 를 하나해서 src 를 새로운 버퍼에 복사한후 다시 이걸 dest 에 복사하고 임시로 잡은 버퍼를 free 하는 그런 구조일 것 같은데요. 그렇게 때문에 memcpy 보다 느리져. 그래서 overlap 이 아니면 빠른 memcpy 를 사용하시고 overlap 이면 memmove 를 사용하시면 되겠네요.

Quote:
The memcpy() function copies n bytes from memory area src to memory area dest. The memory areas may not overlap. Use memmove(3) if the memory areas do overlap.
cdpark의 이미지

devilhero wrote:
아마 memmove 가 내부적으로 malloc 를 하나해서 src 를 새로운 버퍼에 복사한후 다시 이걸 dest 에 복사하고 임시로 잡은 버퍼를 free 하는 그런 구조일 것 같은데요.

실제론 이렇게 복잡하지 않습니다. :)

[1][2][3]

에서 [1][2]를 [2][3] 자리로 복사한다면 뒤에서부터 옮기면 됩니다. [2]를 [3] 자리에 옮기고, [1]을 [2] 자리에 옮기면 되죠.

반대로 [2][3]을 [1][2] 자리에 옮긴다면 앞에서부터 옮기면 되고요.

서로 겹치지 않는다면 아무 순서로 옮겨도 상관없겠죠? :)

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.