The name of the sick
When we write a program, we generally pay attention to the naming of variables, we can let other people basically know the meaning of the variable. memcpy memory copy, no problem; memmove, memory move? Wrong, if you understand this, then you have to take a good look at this article, memmove or memory copy. So since memcpy and Memmove are both memory copies, what's the difference?
First, memcpy.
Have you ever attended a C + + written exam. Let you write the implementation of memcpy, this is how common pen test. Now, pick up your calculus paper and pen; Yes, it's a pen and paper, not for you to write on your IDE. Can't write it? Look below:
Copy Code code as follows:
void *mymemcpy (void *dest, const void *SRC, size_t count)
{
ASSERT (dest!= null | | | src!= NULL);
Char *tmp = (char *) dest;
Char *p = (char *) src;
while (count--)
{
*tmp++ = *p++;
}
return dest;
}
The realization of memcpy is very simple, generally in the written examination, the emergence of the topic of source code, nothing more than to pay attention to the following points:
1. Determine function prototype;
2. Legality of judgment parameters;
3. Logical realization (consider various situations, collectively referred to as logical implementation);
4. Error handling.
Of course, I do not have error handling, and do not need error handling. Above, I wrote the memcpy of the implementation of the source code, the implementation of the principle shown in the following figure:
This way, the above code will run very well, if the following situation occurs?
I, n, K memory and J, E, L of the memory address overlap, and now use the above code for copy, what will happen? Have you ever thought about this problem. If not, think now and don't rush to read the following.
Then I'll leave you with a question, why do I need to convert void * to char * in the code above? Like what:
Copy Code code as follows:
Char *tmp = (char *) dest;
Can leave a message to answer OH.
Besides Memmove
Memmove is also used to achieve a direct copy of memory. Speaking of this name, I personally feel a little bit of a pit. Since Memmove is also used for memory data movement, then first look at the implementation of Memmove source code.
Copy Code code as follows:
void *mymemmove (void *dest, const void *SRC, size_t count)
{
ASSERT (dest!= null | | | src!= NULL)
if (DST < SRC)
{
Char *p = (char *) dest;
Char *q = (char *) src;
while (count--)
{
*p++ = *q++;
}
}
Else
{
Char *p = (char *) dest + count;
Char *q = (char *) src + count;
while (count--)
{
*--p = *--q;
}
}
return dest;
}
From the source view, Memmove is indeed more complex than memcpy; what's more, look more closely? Oh, one more else branch, and it's this else branch that handles the problem of overlapping memory between SRC and dest.
Comparison of memcpy and Memmove
From the realization of the source code can indeed see some of the tricks, when there are src and dest memory overlap time, memmove processing rules are from the back of copy. Of course, the overlap of the question, need to consider the following two kinds of occasions.
As shown in the figure, when a (1) corresponds to the situation, it is necessary to start from the head of SRC copy, that is, the Memmove source code in the If branch, this part of the source code and the implementation of the memcpy is consistent; When the corresponding situation occurs (2), you need to start copying from the tail of SRC, Prevent the occurrence of a covering phenomenon. This is a more memmove than memcpy, so that, in practice, using memmove is safer than memcpy.
Summarize
Summing up here, I feel that I have made the matter clear. You tell me? If you have any good ideas, you are welcome to share with me.