0

I am trying to move memory with possible overlap, using negative or positive increments for the *src and *dst, and without using a large temporary buffer.

I am trying to come up with an efficient replacement for the memmove() function, something along the lines of:

smart_memmove(char *dst, const char *src, size_t num, int dst_inc, int src_inc);

dst and src may overlap, and dst_inc and src_inc may be any positive or negative integer (negative increments denote moving backwards in memory with the starting pointer at the top). I'd like to avoid using a large temporary buffer even if it means a reduction in execution speed.

An example of this would be to copy 10 bytes starting from memory location 0 incrementing at every other byte, to memory location 17 counting backwards by 1:

smart_memmove(17, 0, 10, -1, 2);

Another example would be to, say, reverse 10 series of bytes in memory locations 6, 9, 12, 15, 18, 21, 24, 27, 30, 33 by calling smart_memmove with the following parameters:

smart_memmove(6, 33, 10, 3, -3); /* or... smart_memmove(33, 6, 10, -3, 3); */
Mario S
  • 11,715
  • 24
  • 39
  • 47
  • What is the meaning of `src_inc` and `dst_inc`? – Dietrich Epp Oct 11 '11 at 03:52
  • That's invalid C code, right there. And I still don't know what `dst_inc` means. – Dietrich Epp Oct 11 '11 at 03:54
  • 4
    See http://stackoverflow.com/questions/3572309/memmove-implementation-in-c/3572519#3572519 – paxdiablo Oct 11 '11 at 03:55
  • Oops, you're right! I'll replace void * with char * in the original comment. Thanks! – user613994 Oct 11 '11 at 03:55
  • Still doesn't fix the underlying problem, which is that I have no idea what `dst_inc` is supposed to mean. – Dietrich Epp Oct 11 '11 at 03:57
  • dst_inc increments the destination pointer in memory. src_inc increments the source. src_inc and dst_inc both equaling 1 is similar to calling memmove(dst, src, num), however I'd like this function to specify both the direction and number of steps between each element. – user613994 Oct 11 '11 at 04:03
  • 4
    It's hard to believe that C has survived for 38 years without this function. – Caleb Oct 11 '11 at 04:57
  • 1
    In what way will your function be more efficient than the standard C Library `memmove()`? – wallyk Oct 11 '11 at 05:03
  • It may never be more efficient given that smart_memmove requires many conditionals (something I'd certainly like to avoid.) – user613994 Oct 11 '11 at 06:27
  • Definitely look at the diagram in @paxdiablo's comment, imagining that the start could be at either end of the buffer. It seems like the only time you can't handle overlap by starting from the other end is the case when src_inc and dst_inc have different signs. In that case you need to reverse the overlap region. – AShelly Oct 11 '11 at 06:58
  • src_inc and dst_inc should have different values entirely, as well as different signs. I'm aware of how memmove is implemented, but in this case, the range between *dst's boundary may (or may not) lay completely within *srs' range, or visa versa, or partially. – user613994 Oct 11 '11 at 07:44
  • Writing your function in standard-compliant C may not be one of your objectives, but it appears to be impossible to write a `memmove()` variant in standard C without either the copy or an expensive sequence of pointer `==` tests. http://stackoverflow.com/questions/4023320/how-to-implement-memmove-in-standard-c-without-an-intermediate-copy – Pascal Cuoq Oct 11 '11 at 09:19
  • This function must be written in standard C. – user613994 Oct 11 '11 at 09:30

1 Answers1

-1

You can also prefer the memcpy() function.

void * memcpy ( void * destination, const void * source, size_t num );

destination Pointer to the destination array where the content is to be copied, type-casted to a pointer of type void*.

source Pointer to the source of data to be copied, type-casted to a pointer of type const void*.

num Number of bytes to copy.

size_t is an unsigned integral type.

Copies the values of num bytes from the location pointed by source directly to the memory block pointed by destination.

The underlying type of the objects pointed by both the source and destination pointers are irrelevant for this function; The result is a binary copy of the data.

The function does not check for any terminating null character in source - it always copies exactly num bytes.

To avoid overflows, the size of the arrays pointed by both the destination and source parameters, shall be at least num bytes, and should not overlap (for overlapping memory blocks, memmove is a safer approach).

Sample Program

/* memcpy example */
#include <stdio.h>
#include <string.h>

struct {
  char name[40];
  int age;
} person, person_copy;

int main ()
{
  char myname[] = "user613994";

  /* using memcpy to copy string: */
  memcpy ( person.name, myname, strlen(myname)+1 );
  person.age = 46;

  /* using memcpy to copy structure: */
  memcpy ( &person_copy, &person, sizeof(person) );

  printf ("person_copy: %s, %d \n", person_copy.name, person_copy.age );

  return 0;
}
Praveen Vinny
  • 2,372
  • 6
  • 32
  • 40