Search code examples
cmemcpyvoid-pointers

swap function using memcpy and void*


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

void swap (void *vp1, void *vp2, const size_t size) {
    char *buffer = (char *)malloc(sizeof(char)*size);
    memcpy(buffer, vp1, size);
    memcpy(vp1, vp2, size);
    memcpy(vp2, buffer, size);
    free(buffer);
}

int main()
{
    char *puppy = strdup("Wow");
    char *kitty = strdup("Mew");

    printf("%s, %s\n", puppy, kitty);
    swap(&puppy, &kitty, sizeof(char **));
    printf("%s, %s\n", puppy, kitty);

    free(puppy);
    free(kitty);

    return 0;
}

I'm trying to make practise to understand using void* and memcpy(). In this code at first I thought swap(puppy, kitty, sizeof(char *)); It works. But I don't understand the usage swap(&puppy, &kitty, sizeof(char **)); Could someone explain how the second swap works?


Solution

  • After the following two lines:

    char *puppy = strdup("Wow");
    char *kitty = strdup("Mew");
    

    The memory usage looks something like this:

    puppy
    +-----------+      +---+---+---+-----+
    | address1  |  ->  | W | o | w | \0  |
    +-----------+      +---+---+---+-----+
    
    kitty
    +-----------+      +---+---+---+-----+
    | address2  |  ->  | M | e | w | \0  |
    +-----------+      +---+---+---+-----+
    

    You can implement swap couple of ways:

    Swap Method 1: Change the values of pointers.

    puppy
    +-----------+      +---+---+---+-----+
    | address2  |  ->  | M | e | w | \0  |
    +-----------+      +---+---+---+-----+
    
    kitty
    +-----------+      +---+---+---+-----+
    | address1  |  ->  | W | o | w | \0  |
    +-----------+      +---+---+---+-----+
    

    Swap Method 2: Change the contents of what the pointers point to:

    puppy
    +-----------+      +---+---+---+-----+
    | address1  |  ->  | M | e | w | \0  |
    +-----------+      +---+---+---+-----+
    
    kitty
    +-----------+      +---+---+---+-----+
    | address2  |  ->  | W | o | w | \0  |
    +-----------+      +---+---+---+-----+
    

    If you want the behavior of the first approach, you need to use:

    swap(&puppy, &kitty, sizeof(char*));
    

    If you want behavior of the second approach, you need to use:

    swap(puppy, kitty, strlen(puppy));
    

    Keep in mind that the second approach will be a problem if the strings are of different lengths.