Memory overlap: the copied destination address is within the source address range. Memory overlap means that the copied Destination Address and source address overlap.
The strcpy and memcpy functions do not overlap the memory. When using these two functions, only the programmer can ensure that the source address and target address do not overlap, or use the memmove function to copy the memory.
The memmove function processes memory overlaps.
Now let's look at the strcpy function.
Prototype: extern char * strcpy (char * DEST, char * Source );
Function: Copies the string ending with null indicated by source to the array indicated by DeST.
Note: The memory regions referred to by source and DEST cannot overlap and DEST must have sufficient space to accommodate source strings.
Returns the pointer to DeST.
Overlap is considered in two aspects:
(1). the Dest data overwrites the source; for example, DEST (8 byte) Address: 1000
Source (8 byte): 1002
(2) The region referred to by DEST is originally part of the source; for example, DEST (8 byte) Address: 1000
Source (8 byte): 0998
For example, in the first cross case, DST <SRC and DST + count> SRC, memcpy, and memmove have the same results. See the following example:
String S = "Hello World ";
Memmove (& S [0], & S [5], 10 );
For example:
Int main ()
{Char * P = NULL;
P = (char *) malloc (100 );
Memcpy (P, "123456789", strlen ("123456789"); // wait until the error is returned. There is a length parameter and only CNT can be copied.
// The Byte ends.
Printf ("before P = % s \ n", P );
Strcpy (p + 1, P); // Note: it overlaps here, And strcpy judges '\ 0' in the original string'
Printf ("after P = % s \ n", P );
Free (P );
}
1. Let's take a look at strcpy () prototype: string copy.
Char * strcpy (char * strdest, const char * strsrc)
{
Assert (strdest! = NULL) & (strsrc! = NULL ));
Char * address = strdest;
While (* strdest ++ = * strsrc ++) · 1! = '/0 ')
NULL;
Return address;
}
2. Let's take a look at the prototype of the memcpy function: memory copy
Void * memcpy (void * DEST, const void * Source, size_t count)
{
Assert (null! = DEST) & (null! = Source ));
Char * tmp_dest = (char *) DEST;
Char * tmp_source = (char *) source;
While (count --) // does not judge whether there are overlapping areas
* Tmp_dest ++ = * tmp_source ++;
Return DEST;
}
3. Let's take a look at the prototype of the memmove function:
Void * memmove (void * DEST, const void * Source, size_t count)
{
Assert (null! = DEST) & (null! = Source ));
Char * tmp_source, * tmp_dest;
Tmp_source = (char *) source;
Tmp_dest = (char *) DEST;
If (DEST + count <source) | (source + count) <DEST ))
{// If no overlapping areas exist
While (count --)
* Tmp_dest ++ = * tmp_source ++;
}
Else
{// If there is overlap (reverse copy)
Tmp_source + = count-1;
Tmp_dest + = count-1;
While (count --)
* -- Tmp_dest = * -- TMP;
}
Return DEST;
}
In-depth analysis:
Void * memcpy (void * DST, const void * SRC, size_t count ):
Void * memmove (void * DST, const void * SRC, size_t count );
Let's take a look at a test:
# Include <string. h>
# Include <stdio. h>
Int main ()
{Int A [10];
For (INT I = 0; I <10; I ++)
A [I] = I;
Memcpy (& A [4], A, sizeof (INT) * 6); // The result is: 1 2 3 0 1 2 3 0 1
// Memcpy (& A [4], A, sizeof (INT) * 6); // The result is: 1 2 3 0 1 2 3 0 1 (VC is the same as the following one)
// Memmove (& A [4], A, sizeof (INT) * 6); // The result is: 1 2 3 0 1 2 4 5
// Memmove (& A [4], A, sizeof (INT) * 6); // The result is: 1 2 3 0 1 2 4 5
// Memmove (A, & A [4], sizeof (INT) * 6); // The result is: 5 6 7 8 9 6 7 8 9
// Memmove (A, & A [4], sizeof (INT) * 6); // The result is: 5 6 7 8 9 6 7 8 9
// Memcpy (A, & A [4], sizeof (INT) * 6); // The result is: 5 6 7 8 9 6 7 8 9
// Memcopy (A, & A [4], sizeof (INT) * 6); // The result is: 5 6 7 8 9 6 7 8 9
For (I = 0; I <10; I ++)
Printf ("% d", a [I]);
Printf ("/N ");
Return 0;
}
They all copy count bytes from the memory indicated by Src to the memory indicated by DST, and return the DST value. When the source and target memory regions do not overlap, the results are the same. But it is different when there is crossover. There are two types of cross-origin memory and target memory: (low address on the left)
That is, DST <= SRC and DST + count> SRC
For the first cross case, DST <= SRC and DST + count> SRC, memcpy and memmove have the same results. See the following example:
Int A [] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Memcpy (A, A + 4, sizeof (INT) * 6); and
Memmove (A, A + 4, sizeof (INT) * 6); the results are the same: 4567896789
In the second case, Src <DST and SRC + count> DST, memcpy and memmove have different results. See the following example:
Int A [] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
Memcpy (a + 4, A, sizeof (INT) * 6) The result should be: 0123012301
But it is running on vs2005: 0123012345 (please tell me the reason if you know it)
Memmove (a + 4, A, sizeof (INT) * 6) Result: 0123012345
Summary:
1. when the SRC and DEST memory areas overlap, memmove can ensure that the first n Bytes of the SRC memory area can be correctly copied to the memory in the Dest;
2. When the SRC address is lower than the Dest address, the results are the same. In other words, the difference between memmove and memcpy is only reflected in the case that the head of DeST overlaps with the tail of SRC;
To sum up, when considering memory overlap, strcpy and memcpy should make a judgment on memory overlap:
For memcpy, you need to add an asserted:Assert (DST <= SRC | SRC + count <DST );
The source and DEST memory regions cannot overlap and the Dest must have enough space to hold the source string.
Returns the pointer to DeST.
For strcpy, an asserted must be added:
Int COUNT = strlen (SRC) + 1; // SRC Length
Assert (DEST <SRC | DEST> (SRC + count ))
Memcpy,Equivalent to memmove
Strcpy, a string copy function with overlapping memory
Char * strcpy (char * DEST, const char * SRC)
{
Char * D = DEST; // backup Input
Char * s = SRC;
Int COUNT = 0;
Assert (DEST); // non-null pointer check
Assert (SRC );
If (src = DEST)
Return SRC;
Count = strlen (SRC) + 1; // SRC Length
If (count <= 1)
Return 0; // empty SRC
If (DEST <SRC | DEST> (SRC + count ))
{
While (count --)
* D ++ = * s ++;
}
Else // DEST is located in the middle of SRC + count,
{
D = DEST + count;
S = SRC + count;
While (count --)
* D -- = * s --; // reverse copy
}
From: http://blog.csdn.net/feitianxuxue/article/details/7195158