Deep understanding of memory overlapping

Source: Internet
Author: User

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.