Dimpl
Dimpl

Reputation: 942

Swapping values by pointer

I feel like this probably isn't the best idea, but I've implemented a generic swap function in C like so:

void swap(void** p1, void** p2) {
    void* temp = *p1;
    *p1 = *p2;
    *p2 = temp;
}

However, I am having difficulties calling this function. swap(&&a, &&b) for integers a and b doesn't work as '&&' is the label operator, and swap(&(&a), &(&b)) gives the error 'lvalue required as unary '&' operand'. How should I call this function?

Edit: changed variable names for clarity

Edit: I'm trying to do the following, but, as &a and &b seem to be read-only ('lvalue required as left operand of assignment'), it doesn't work:

int a = 5;
int b = 3;
int* temp = &a;
&a = &b;
&b = temp;
assert(a == 3);
assert(b == 5);

Upvotes: 1

Views: 302

Answers (4)

user1196549
user1196549

Reputation:

You are right on one point: this probably isn't the best idea.

You are not swapping two pieces of data, you are swapping the values two pointers that happen to point to them, but the data stays in place.

Assume for instance

int a= 3, b= 5;
int* pa= &a, * qa= &a, * pb= &b, * qb= &b;

After your "swap" is called with pa and pb, a and b still contain 3 and 5, pa points to 5 and pb to 3, but qa still points to 3 and qb to 5.

Also note that without two properly initialized pointer variables, you just can't call your swap.

Upvotes: 1

muXXmit2X
muXXmit2X

Reputation: 2765

As n.m. pointed out, to get a real generic swap function you should consider using memcpy. It can be used as a generic assignement.

Your swap will then look like this:

void swap(void *a, void *b, size_t s)
{
    void *tmp = malloc(s);
    if (tmp) 
    {
        memcpy(tmp, a, s);
        memcpy(a, b, s);
        memcpy(b, tmp, s);
    }
    free(tmp);
}

And can be used like so:

#define MAX 256

int main()
{
    // works for primitive types
    int a = 4, b = 5;
    swap( &a, &b, sizeof(int));
    printf("%d %d\n", a , b);

    // as well as for pointers
    char cA[MAX] = "World!";
    char cB[MAX] = "Hello ";
    swap( &cA, &cB, MAX); 
    printf("%s%s\n", cA, cB); 
}

This will safely swap the values without the need of pointers to pointers.

Upvotes: 3

Vitalii Paprotskyi
Vitalii Paprotskyi

Reputation: 389

int varA = 5, varB = 10;
int *pA = &varA;
int *pB = &varB;
swap((void**)&pA, (void**)&pA);

Now pA points to varB and pB points to varA

Upvotes: 0

R Sahu
R Sahu

Reputation: 206577

You cannot use swap(&(&l_limit), &(&u_limit)) since &l_limit evaluates to a temporary rvalue pointer whose address cannot be taken. Same problem exists for &&u_limit also.

You need to use:

void* ptr1 = &l_limit;
void* ptr2 = &u_limit;
swap(&ptr1, &ptr2);

Upvotes: 6

Related Questions