What is overlapping in memmove() definition?
Asked Answered
F

1

10

I was reading from a c++ reference about memcpyand memmove and they seems to be doing the same thing except that memmove has a specific think called (allowing the destination and source to overlap).

What is overlapping and when that happens?

Fulton answered 22/12, 2013 at 2:18 Comment(1)
overlapping is the usual definition....it means contiguous memory overlapSodomy
C
13

It's very simple. Consider memmove(dest, source, length).

If the range of bytes specified by the range source to source + length - 1 include any bytes in the range specified by dest to dest + length - 1, the two ranges overlap.

This is most likely to happen when moving elements within an array. Example:

// Slide array down by one:
char array[N];
memmove( (void*) &array[0], (void*) &array[1], N - 1 );

That overlaps on elements 1 through N-2. Sliding the other direction has a similar overlap:

// Slide array up by one:
memmove( (void*) &array[1], (void*) &array[0], N - 1 );

If you were to attempt this same operation with memcpy(), the resulting behavior is undefined. Some implementations will work correctly if you use memcpy in both examples above. Others will fail for one or both of the two if you use memcpy here instead of memmove. This is a consequence of the fact C and C++ leave the behavior undefined for memcpy() when the ranges overlap like this.

Cosme answered 22/12, 2013 at 2:19 Comment(7)
Or (POSIX): "The memcpy() function shall copy n bytes from the object pointed to by s2 into the object pointed to by s1. If copying takes place between objects that overlap, the behavior is undefined." memmove allows the objects to overlap - and to gives expected results.Friction
@Joe Z In your exemple will be the source lost or it will be copyed to other space in memory?Fulton
@rullof: Undefined behavior means "anything could happen," including reformatting your hard drive. Most likely, though, the destination gets a garbled result, such as repeating strings of bytes. And because destination and source overlap, that naturally means the source also gets corrupted. I don't think I've witnessed memcpy() writing to bytes outside the range dest to dest + length - 1 even when src/dest overlap. (ie. it will typically only corrupt the memory you asked it to write to.)Cosme
@JoeZ I was refering to using memmove that allows overlap and not memcpy!?Fulton
@Fulton : Oh, ok. For memmove(), it copies from source to destination as if it moved through a third buffer that didn't overlap with either. (In practice, there's no third buffer. The as-if wording is there in the specification for esoteric reasons.) When source and destination overlap, the portion of the source that overlaps the destination will get overwritten by the end of the memmove(), for the simple reason that you need to write the entire result at the destination.Cosme
@JoeZ So what is the solution?Fulton
@rullof: What do you mean by "solution"? I'm not sure what you perceive the problem to be. memmove will correctly move bytes from source to destination, even when they overlap. That necessarily overwrites part of the source in the range where they overlap. The destination will have the correct data.Cosme

© 2022 - 2024 — McMap. All rights reserved.