Fayeure
Fayeure

Reputation: 1369

Swap function that works for any types in C

I don't know if it's possible but I'm trying to do a swap function that swaps two variables and works for any type of variable as long as the two variables to swap are of the same type, what I did is using void * type:

#include <limits.h>
#include <stdio.h>

void ft_swap(void **a, void **b)
{
    void    *tmp;

    tmp = *a;
    *a = *b;
    *b = tmp;
}

int main(void)
{
    int a = 5;
    int b = INT_MAX;
    unsigned long c = 10;
    unsigned long d = ULONG_MAX;

    printf("BEFORE\na = %d\nb = %d\nc = %zu\nd = %zu\n", a, b, c, d);
    ft_swap((void **)&a, (void **)&b);
    ft_swap((void **)&c, (void **)&d);
    printf("AFTER\na = %d\nb = %d\nc = %zu\nd = %zu\n", a, b, c, d);
    return (0);
}

The output is:

BEFORE
a = 5
b = 2147483647
c = 10
d = 18446744073709551615
AFTER
a = 0
b = 5
c = 18446744073709551615
d = 10

I know that void * type is the same size as unsigned long, but can someone explain my what's wrong with the int variables, for me it should work as int is a smaller type? the 5 got swapped, but INT_MAX became 0, what happened here?

EDIT: I did a version as you told me: using long long pointer but it also doesn't work, it changes the value of the int.

Upvotes: 1

Views: 348

Answers (1)

0___________
0___________

Reputation: 67476

Your swap function makes no sense at all (I can't even guess what is the idea behind it).

Your function has to know references to the objects and their size. Then it needs to copy the memory occupied by them.

Here you have the more correct one:

void swap(void *d1, void *d2, size_t size)
{
    unsigned char temp[size];

    memcpy(temp, d1, size);
    memcpy(d1, d2, size);
    memcpy(d2, temp, size);
}

struct st
{
    int a;
    double b;
    char c[10];
};

int main(void)
{
    int a = 5;
    int b = INT_MAX;
    unsigned long c = 10;
    unsigned long d = ULONG_MAX;
    struct st x = {1,2.0, "text1"};
    struct st y = {5,20.0, "text2"};


    printf("BEFORE\na = %d\nb = %d\nc = %zu\nd = %zu\n", a, b, c, d);
    swap(&a, &b, sizeof(a));
    swap(&c, &d, sizeof(c));
    printf("AFTER\na = %d\nb = %d\nc = %zu\nd = %zu\n", a, b, c, d);
    printf("struct before: %d %f %s, %d %f %s\n", x.a, x.b, x.c, y.a, y.b, y.c);
    swap(&x, &y, sizeof(x));
    printf("struct after: %d %f %s, %d %f %s\n", x.a, x.b, x.c, y.a, y.b, y.c);
    return (0);
}

https://godbolt.org/z/er95YYjca

Upvotes: 3

Related Questions