2

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!

Cameron
  • 96,106
  • 25
  • 196
  • 225

5 Answers5

4

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.

Kevin
  • 25,207
  • 17
  • 54
  • 57
3

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);
}
Zan Lynx
  • 53,022
  • 10
  • 79
  • 131
  • nm[a] and nm[b] not const. Also, the swap function you wrote is not very safe since it allows any pointer to a character. – Kevin Sep 24 '08 at 04:38
  • If nm[a] is not const, then let me see you change its value. :) – Zan Lynx Sep 24 '08 at 06:01
  • I think your explanation could've been strengthened if you mentioned that char nm[MAX1][MAX2] is actually transformed by the compiler into char[MAX1 * MAX2], which is just a contiguous piece of memory storing just the characters. Forget const! There are simply no pointers in the array. – Alexander Sep 25 '08 at 22:28
3

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.

Hugh Allen
  • 6,509
  • 1
  • 34
  • 44
  • Unless the OP had a reason for MAX2, this is the absolute correct answer. I was about to post it myself. I hope it bubbles up to the top. :) – Jim Buck Sep 24 '08 at 05:41
1

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.

graham.reeds
  • 16,230
  • 17
  • 74
  • 137
0
void swapPointers(char** ppa, char** ppb)
{
    char* ptemp = *ppa;
    *ppb = *ppa;
    *ppa = ptemp;
}

swapPointers(&nm[0], &nm[1]);
Ana Betts
  • 73,868
  • 16
  • 141
  • 209
  • Hmmm, not quite, Paul: `Error: cannot convert parameter 1 from 'char (*)[10]' to 'char **'` I get the same error with the original code that I posted (and type-casting creates run-time logic errors in both cases). – Cameron Sep 24 '08 at 02:49