Way back when I first started C programming, I wanted to find an easy way to copy one block of memory to another block of memory. The first thing I discovered when digging through documentation was the memcpy() function, which basically does exactly what its name indicates -- copy memory from one location to another. The documentation also talked about a related function called memmove(), which I thought must "move memory from one location to another," so I didn't pay it much attention as I wanted to copy memory, not move it. Yeah, I knew that memcpy() wouldn't behave if the memory regions you were copying overlapped, but I was like "okay, I just won't be stupid and copy between overlapping regions," and, fortunately, the way I used it over the years happened to never result in a situation were those regions would overlap (I think... I've written a lot of code, but don't recall ever debugging an issue due to a bizarre memcpy()-related corruption).
Anyway, over the past couple of days, I've seen tweets from programmers I have great respect for talking about preferring memmove() to memcpy(). It first started with this tweet from John Carmack:
teeny tiny style advance: I've started to always use memmove instead of memcpy. If the dir check impacts performance, fix the architecture.— John Carmack (@ID_AA_Carmack) May 31, 2016
Later on, I saw that another programmer I have a lot of respect for, Rob Pike, fill in some more info on memmove():
I asked the ANSI C89 committee to make memcpy safe, and they gave us memmove instead. I've used memmove ever since. https://t.co/eNWjCTpJCi
— Rob Pike (@rob_pike) June 1, 2016
So apparently, memmove() was supposed to be a safer version of memcpy(), but instead of just making memcpy() safer, they added a new function with a slightly misleading name (and yeah, I realize, when I think about it, that you can't really move memory and all moves are really copies to an extent, so bear with me here). I did a bit more research on it, and found out that the reason why most C programmers stuck to memcpy(), even when when memmove() was available, was due to some sort of believe that memcpy() would be faster (which, in most cases, it probably isn't, and on some systems memcpy() is simply aliased to memmove()). In my case, however, it was simply because when I first learned C, memcpy() did what I needed and I never bothered learning about memmove().
Oddly enough, despite not knowning about how memmove() was safer than memcpy(), I had, at least since graduating from college, always used strncpy() (or similar functions, like strlcpy(), when available) instead of strcpy() for safety reasons. I think part of that was due to the danger of strcpy() being very much in the news at the time, whereas memcpy() never got the same sort of attention, but my memory could be failing me here.
Going forward, I'll always be using memmove() instead of memcpy() where applicable. It also goes to show that one should never stop learning when it comes to programming. You'll never know when something you've been doing for years turns out to be the wrong way to do things (or at least not as good/safe/etc. as another way).Share on Twitter Share on Facebook