I have an array that contains pointers. How can I swap two pointers - say array[1] and array[4] - correctly?
Asked
Active
Viewed 5,433 times
5
-
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 Answers
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
-
-
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
-
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
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
-
-
I imagined someone would suggest that. If they didn't already, someone will! It's too evil :) – Remo.D Jan 19 '10 at 14:13
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
-
2Though you need to check that 1 != 4 or else you leak memory, by nulling a pointer. – JPvdMerwe Jan 19 '10 at 14:14
-
1Tempted to give you -1 for "much clearer" which is obviously wrong. But the answer works so I'll refrain from downvoting. :-) – Graeme Perrow Jan 19 '10 at 14:19
-
-
-
1@JP: Is the check really required? If both are equal, then the three steps will be: array[1] = 0; array[4] = array[4]; array[1] = array[4], which will make everything okay... or am I missing something? – Johan Jan 19 '10 at 14:42
-
@Johan: no, he's saying that the code wouldn't work if it were called to swap `array[1]` with `array[1]`. – Stephen Canon Jan 19 '10 at 14:51
-
@Johan: JP was right. My edit was wrong. It just isn't need in this case because 1 != 4 usually. – Richard Pennington Jan 19 '10 at 15:19
-
@Stephen: See http://stackoverflow.com/questions/1995113/strangest-language-feature/1995476#1995476 ;-) – Richard Pennington Jan 19 '10 at 15:39
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