tags:

views:

2872

answers:

6

Hello,

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!

A: 
void swapPointers(char** ppa, char** ppb)
{
    char* ptemp = *ppa;
    *ppb = *ppa;
    *ppa = ptemp;
}

swapPointers(&nm[0], &nm[1]);
Paul Betts
A: 

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
+3  A: 

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
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
If nm[a] is not const, then let me see you change its value. :)
Zan Lynx
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
+3  A: 

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
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
+4  A: 

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
Good answer. I've provided clarification against this confusion here: http://stackoverflow.com/questions/274865/pointer-question-in-c#274943
Johannes Schaub - litb
+1  A: 

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