std::memmove(3)

πŸ“¦ version 2024.07.05, in nixpkgs unstable, opensuse-leap 16.0

πŸ’… NAME

okay so bestie, meet std::memmove β€” the function's whole name is literally std::memmove, no cap. She's the overlapping-copy queen and she's about to eat πŸ’–


✨ SYNOPSIS ✨

First thing's first, she lives here:

Defined in header <cstring>

And here's her whole signature, look at her:

void* memmove( void* dest, const void* src, std::size_t count );

So what she does: she copies count characters from the object pointed to by src over to the object pointed to by dest. Both of those objects get reinterpreted as arrays of unsigned char β€” that's just the vibe, that's how she sees the world πŸ¦‹

And here's the iconic part, the reason she's the main character: the objects may overlap πŸ”₯ Copying takes place as if the characters were first copied into a temporary character array, and then copied from that array into dest. Like she's got a little staging area. So chill.

⚠️ But listen. If either dest or src is an invalid or null pointer, the behavior is undefined β€” even if count is zero. Yeah. Even then. Even with zero. Not a drill πŸ’€
⚠️ Also: if the objects are potentially-overlapping or not TriviallyCopyable, the behavior of memmove is not specified and may be undefined. So like… know your types, bestie πŸ™ˆ

πŸŽ€ PARAMETERS πŸŽ€

  • dest β€” pointer to the memory location to copy to (the destination, the place we're moving into)
  • src β€” pointer to the memory location to copy from (the source, the thing we're copying)
  • count β€” number of bytes to copy

πŸ‘‘ RETURN VALUE πŸ‘‘

She returns dest. That's it. That's the return. Short king energy but make it a pointer 🫢


🌸 NOTES 🌸

  • std::memmove may be used to implicitly create objects in the destination buffer. Slay.
  • Okay so this is so funny β€” even though she's specified "as if" a temporary buffer is used, actual implementations of this function do not incur the overhead of double copying or extra memory πŸ’… Like, she's not actually allocating your little staging array, that's just the description. For small count, it may load up and write out registers; for larger blocks, a common approach (glibc and bsd libc) is to copy bytes forwards from the beginning of the buffer if the destination starts before the source, and backwards from the end otherwise, with a fall back to std::memcpy when there is no overlap at all. That's the tea β˜•
  • Where strict aliasing prohibits examining the same memory as values of two different types, std::memmove may be used to convert the values. Iconic loophole behavior, honestly.

🧚 EXAMPLE 🧚

// Run this code

#include <cstring>
#include <iostream>

int main()
{
    char str[] = "1234567890";
    std::cout << str << '\n';
    std::memmove(str + 4, str + 3, 3); // copies from [4, 5, 6] to [5, 6, 7]
    std::cout << str << '\n';
}

⭐ Output:

1234567890
1234456890

See how the 1 and 2 and 3 stayed put and everything shifted? She did that. Overlapping region and all πŸ’œ


🌈 SEE ALSO 🌈

  • memcpy β€” copies one buffer to another (function)
  • memset β€” fills a buffer with a character (function)
  • wmemmove β€” copies a certain amount of wide characters between two, possibly overlapping, arrays (function)
  • copy β€” copies a range of elements to a new location
  • copy_if β€” (function template) (C++11)
  • copy_backward β€” copies a range of elements in backwards order (function template)
  • is_trivially_copyable β€” (C++11) checks if a type is trivially copyable (class template)
  • C documentation for memmove

okay that's the whole page, go forth and copy your overlapping bytes responsibly πŸ“

from http://cppreference.com, dated 2024.06.10, and this is std::memmove(3) signing off β€” mwah πŸ’‹

πŸ“¦ where this page comes from