Thread: Memmove

    #1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    30
    Rep Power
    2

    Memmove


    Can someone tell me how to implement memmove() function ?
  2. #2
  3. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,406
    Rep Power
    1871
    Do you know how to implement memcpy()?

    Do you know how to detect if two memory blocks overlap?
    Originally Posted by man page
    The memmove() function copies n bytes from memory area src to memory area dest. The memory areas may overlap: copying takes place as though the bytes in src are first copied into a temporary array that does not overlap src or dest, and the bytes are then copied from the temporary array to dest.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    30
    Rep Power
    2

    Nope


    Originally Posted by salem
    Do you know how to implement memcpy()?

    No, I never tried.

    Do you know how to detect if two memory blocks overlap?
    No.
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Aug 2012
    Posts
    156
    Rep Power
    34
    You can basically copy in two directions: from the front or from the back.

    So, to write memmove() you need to check if the memory areas overlap.
    If they don't overlap, just copy from any direction.

    If they overlap, choose the direction of copying based on what parts overlap.

    If the destination first byte is within the source range copy backwards from the end
    if the destination last byte is within the source range copy frontwards from the beginning.
  8. #5
  9. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,406
    Rep Power
    1871
    Well I suggest you start by trying to implement memcpy then.

    Then use it to do some copying on the following.
    Code:
    #include<stdio.h>
    #include<string.h>
    int main()
    {
        char t1[] = "0123456789";
        char t2[] = "0123456789";
        char t3[] = "0123456789";
        char t4[] = "0123456789";
    
        memcpy(&t1[5],&t1[3],5);
        memcpy(&t2[3],&t2[5],5);
    
        memmove(&t3[5],&t3[3],5);
        memmove(&t4[3],&t4[5],5);
    
        printf("Cpy=%s\nCpy=%s\nMov=%s\nMov=%s\n", t1, t2, t3, t4);
        return 0;
    }
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    30
    Rep Power
    2
    Originally Posted by salem
    Well I suggest you start by trying to implement memcpy then.

    Then use it to do some copying on the following.
    Code:
    #include<stdio.h>
    #include<string.h>
    int main()
    {
        char t1[] = "0123456789";
        char t2[] = "0123456789";
        char t3[] = "0123456789";
        char t4[] = "0123456789";
    
        memcpy(&t1[5],&t1[3],5);
        memcpy(&t2[3],&t2[5],5);
    
        memmove(&t3[5],&t3[3],5);
        memmove(&t4[3],&t4[5],5);
    
        printf("Cpy=%s\nCpy=%s\nMov=%s\nMov=%s\n", t1, t2, t3, t4);
        return 0;
    }
    Hope this is correct for memcpy

    void memcpy(char *dest,char *src,int amount)
    {
    while(amount--)
    {
    *dest++=*src++;
    }
    }
  12. #7
  13. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,406
    Rep Power
    1871
    > Hope this is correct for memcpy
    Did you try it in my test program, replacing the standard library memcpy with your version?

    What results did you see?

    How about with different data types?
    Code:
    int a[] = { 1, 2, 3, 4, 5 };
    int b[5];
    memcpy(b,a,sizeof(b));
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    30
    Rep Power
    2

    Complete program


    Hi Salem. I am using codepad.org to run.

    I have got the output as

    Cpy=0123434343
    Cpy=0125678989
    Mov=0123434567
    Mov=0125678989


    #include<stdio.h>
    #include<string.h>

    int main()
    {
    char t1[] = "0123456789";
    char t2[] = "0123456789";
    char t3[] = "0123456789";
    char t4[] = "0123456789";

    memcopy(&t1[5],&t1[3],5);
    memcopy(&t2[3],&t2[5],5);

    memove(&t3[5],&t3[3],5);
    memove(&t4[3],&t4[5],5);

    printf("Cpy=%s\nCpy=%s\nMov=%s\nMov=%s\n", t1, t2, t3, t4);
    return 0;
    }

    void memove(char *dest,char *src,unsigned int amount)
    {
    int i=0;
    int flag = 0;
    char temp[100];

    for(i=0;i<amount;i++)
    {
    if((src+i) == dest)
    {
    strcpy(temp,src);
    memcopy(dest,temp,amount);
    flag = 1;
    }
    else if((dest+i) == src)
    {
    strcpy(temp,src);
    memcopy(dest,temp,amount);
    flag =1;
    }
    }
    if(flag == 0)
    memcopy(dest,src,amount);
    }
    void memcopy(char *dest,char *src,int amount)
    {
    while(amount--)
    {
    *dest++=*src++;
    }
    }

    Hope this logic is correct.
  16. #9
  17. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,406
    Rep Power
    1871
    > Hope this logic is correct.
    1. Where are your code tags, to make your code readable.

    2. No, it's not right
    - char temp[100];
    What happens if you try to copy several megabytes?

    - strcpy(temp,src);
    What happens if you try to copy something other that a string?

    > copying takes place as though the bytes in src are first copied into a temporary array that does not overlap src or dest
    It only needs to behave like this, which is not the same as this is how it is implemented.
    Re-read bdb's post.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  18. #10
  19. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    30
    Rep Power
    2

    Comments taken.


    Salem, I have handled the points which you have mentioned.
    Can you check once ?

    #include<stdio.h>
    #include<string.h>

    int main()
    {
    char t1[] = "0123456789";
    char t2[] = "0123456789";
    char t3[] = "0123456789";
    char t4[] = "0123456789";

    memcopy(&t1[5],&t1[3],5);
    memcopy(&t2[3],&t2[5],5);

    memove(&t3[5],&t3[3],5);
    memove(&t4[3],&t4[5],5);

    printf("Cpy=%s\nCpy=%s\nMov=%s\nMov=%s\n", t1, t2, t3, t4);
    return 0;
    }

    void memove(void* destination,void* source,unsigned int amount)
    {
    char *dest = (char *)destination; // Converting void pointer into char pointer
    char *src = (char *)source;

    int loop_count=0; //for loop count
    int count=0;
    int flag = 0; // To check for overlapping address

    //Loop to determine overlapping address
    for(loop_count=0;loop_count<amount;loop_count++)
    {
    if((src+loop_count) == dest) // For destination first byte within source range
    {
    count = amount;
    while(amount--)
    {
    *(dest+amount) = *(src+amount);
    }
    amount = count;
    flag = 1;
    }
    else if((dest+loop_count) == src) // For destination last byte within source range
    {
    memcopy(dest,src,amount);
    flag =1;
    }
    }
    if(flag == 0) // No overlapping of addresses
    memcopy(dest,src,amount);
    }

    void memcopy(void* destination,void* source,int amount)
    {
    char *dest = (char *)destination;
    char *src = (char *)source;

    while(amount--) // Copying from starting
    {
    *dest++=*src++;
    }
    }
  20. #11
  21. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    30
    Rep Power
    2
    Originally Posted by bdb
    You can basically copy in two directions: from the front or from the back.

    So, to write memmove() you need to check if the memory areas overlap.
    If they don't overlap, just copy from any direction.

    If they overlap, choose the direction of copying based on what parts overlap.

    If the destination first byte is within the source range copy backwards from the end
    if the destination last byte is within the source range copy frontwards from the beginning.
    Thanks bdb.
  22. #12
  23. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,406
    Rep Power
    1871
    > Can you check once ?
    Well it's hard to be motivated when you keep posting code without using [code][/code] tags.

    Also, where are your results?

    Also, how do they compare to the results you get with using the standard library memmove and memcpy?

    If your memove() gives the same result as the library memmove(), then I'd say you're well on your way. Try some more tests.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  24. #13
  25. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    30
    Rep Power
    2
    Originally Posted by salem
    > Can you check once ?
    Well it's hard to be motivated when you keep posting code without using [code][/code] tags.

    Also, where are your results?

    Also, how do they compare to the results you get with using the standard library memmove and memcpy?

    If your memove() gives the same result as the library memmove(), then I'd say you're well on your way. Try some more tests.

    New to devshed. So still exploring the things. Will use code tags from now on.

    Output of my code

    Cpy=0123434343
    Cpy=0125678989
    Mov=0123434567
    Mov=0125678989


    I am getting output in standard lib as

    Cpy=0123434367 => I heard for overlapping addresses memcpy result will be unpredictable. Is that so ?
    Cpy=0125678989
    Mov=0123434567
    Mov=0125678989
  26. #14
  27. Contributed User
    Devshed Specialist (4000 - 4499 posts)

    Join Date
    Jun 2005
    Posts
    4,406
    Rep Power
    1871
    > I heard for overlapping addresses memcpy result will be unpredictable. Is that so ?
    Read the manual page
    The memcpy() function copies n bytes from memory area s2 to memory area
    s1. If s1 and s2 overlap, behavior is undefined. Applications in which
    s1 and s2 might overlap should use memmove(3) instead.
    Do you see why we have memmove() and memcpy().

    "behavior is undefined" is a key phrase in C programming. Learn to recognise it in manual pages and the language definition itself.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper
  28. #15
  29. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Oct 2012
    Posts
    30
    Rep Power
    2
    Originally Posted by salem
    > I heard for overlapping addresses memcpy result will be unpredictable. Is that so ?
    Read the manual page

    Do you see why we have memmove() and memcpy().

    "behavior is undefined" is a key phrase in C programming. Learn to recognise it in manual pages and the language definition itself.
    Yes. Thankyou.

IMN logo majestic logo threadwatch logo seochat tools logo