5

I have an array that contains pointers. How can I swap two pointers - say array[1] and array[4] - correctly?

Pieter
  • 31,619
  • 76
  • 167
  • 242
  • Now that I see your other questions on arrays, I need to ask: are those function pointers? If they are, solutions using `void *` are not guaranteed to work. – Remo.D Jan 19 '10 at 14:28
  • I'm performing the swap on an int array that holds pointers like this: myPointerArray[0] points to array[0], myPointerArray[1] points to array[1] and so on. Can that cause problems? – Pieter Jan 19 '10 at 14:42
  • The only problem is if you mix pointers to data and pointers to functions. On some architecture data and functions have to separate addressing space and you can't do things like: `int f(); void *p; ... p = f;`. If I get what you say you should be ok but you probably post some more code to be sure. – Remo.D Jan 19 '10 at 14:51

5 Answers5

5

You need a temporary variable:

void*temp = array[4];
array[4]=array[1];
array[1] = temp;

Edit Fixed first line.

martinr
  • 3,794
  • 2
  • 17
  • 15
  • Line 1 should be array[4], no? – ezod Jan 19 '10 at 14:08
  • Your code is wrong, just a confusion of array indexes. It's copying array[1] to temp, then overwriting array[4] and putting temp back in to array[1]. – Tony Jan 19 '10 at 14:08
  • 1
    Void is only a pointer, without actually specifing a datatype. – Pindatjuh Jan 19 '10 at 14:08
  • In your code it would be whatever the type of the array is. If you have int* array[N], where N is some size, or int** array, where array points at an array held elsewhere, it would be int*. – martinr Jan 19 '10 at 14:09
  • @Pieter, the type is `void *`, i.e., pointer to `void`. The C standard guarantees that any object pointer can be converted to `void *` and back—thus, making above independent of the type of pointers inside `array`. – Alok Singhal Jan 20 '10 at 03:16
5
void* temp = array[1]; 
array[1] = array[4]; 
array[4] = temp;
Tony
  • 9,672
  • 3
  • 47
  • 75
3

The most correct way is using a temporary variable as in :

void *tmp_pointer;

....
tmp_pointer = array[1];
array[1] = array[4];
array[4] = tmp_pointer;
....

Stay away from any evil bit or int hacks! :)

Let me add here that we should have asked "what type of pointer?"

In theory, you can't safely mix pointers to data and pointers to function. The C standard does not guarantee that this would be meaningful or possible at all. It only ensures that:

  • data pointers can be converted back and from void *
  • ((void *)0) is a pointer that is different from any data pointer or function pointer
  • function pointers of one type can be converted to function pointers of another type and back.

I understand that this is because in some architecture, the address space for data is completely separated from the address space for functions and you can't safely convert from on type of pointers to the other and back.

Remo.D
  • 16,122
  • 6
  • 43
  • 74
1
#include <stdint.h>
if (1 != 4) {
    array[1] = (void*)((intptr_t)(array[1]) ^ (intptr_t)(array[4]));
    array[4] = (void*)((intptr_t)(array[1]) ^ (intptr_t)(array[4]));
    array[1] = (void*)((intptr_t)(array[1]) ^ (intptr_t)(array[4]));
}

Is much clearer and saves a temporary. ;-)

Richard Pennington
  • 19,673
  • 4
  • 43
  • 72
0

My C is quite rusty, but a simple

int* foo = array[4];
array[4] = array[1];
array[1] = foo;

should suffice.

alrevuelta
  • 186
  • 2
  • 13