Transparently swapping pointers to character arrays in C++
Question
I have a 2D character array:
char nm[MAX1][MAX2] = { "john", "bob", "david" };
I want to swap two of these elements (without std::swap
) by simply writing
swapPointers(nm[0], nm[1]);
where swapPointers
looks like this
void swapPointers(char *&a, char *&b)
{
char *temp = a;
a = b;
b = a;
}
However, this does not compile (and while adding casts makes it compile, the pointers end up pointing to wrong/weird locations).
Can anybody help?
Thanks!
Solution
Zan is close, but his problem is that his 'swap' function can take any pointer to characters. This can cause problems if misused. Here is a safer version:
void swap(char (&x)[MAX2], char (&y)[MAX2])
{
char temp[MAX2];
memcpy(temp, x, MAX2);
memcpy(x, y, MAX2);
memcpy(y, temp, MAX2);
}
There is also a misunderstanding on the part of the poster: 'nm' is a 2-dimensional array of characters. There are no pointers. nm[0], nm[2], etc... are also not pointers either -- they are still (1-dimensional) arrays. The fact that 1-dimensional arrays are implicitly convertible to pointers causes this type of confusion among many C and C++ programmers.
In order to swap the data in the 2-dimensional array, you have to swap blocks of memory of size MAX2 -- as indicated by both 'swap' functions Zan and I wrote.
OTHER TIPS
You cannot swap those pointers by reassigning the pointers, because those pointers point into a 2-D character array.
nm[a] and nm[b] are very strongly const
because nm is a truly const
object. If it wasn't, you could move C variables around in RAM by reassigning their names.
Just think of the havoc! So you can't do that. :-)
To swap what those pointers point to, you need to swap the values in those array locations.
swap(char *a, char *b)
{
char temp[MAX1];
memcpy(temp, a, MAX1);
memcpy(b, a, MAX1);
memcpy(a, temp, MAX1);
}
Your swapPointers()
swaps pointers, whereas you're trying to pass it arrays.
If you change
char nm[MAX1][MAX2]
to
char *nm[MAX1]
and fix the small bug in swapPointers()
(last line should be b = temp;
), it works.
The real point is, if you are using c++ then you should be using a std::vector of std::string instead:
std::vector<std::string> nm;
nm.push_back( "john" );
nm.push_back( "bob" );
nm.push_back( "david" );
std::swap( nm[0], nm[1] );
Note: not tested.
void swapPointers(char** ppa, char** ppb)
{
char* ptemp = *ppa;
*ppb = *ppa;
*ppa = ptemp;
}
swapPointers(&nm[0], &nm[1]);