views:

257

answers:

7

I have two arrays of pointers to doubles that I need to swap. Rather than just copy the data within the arrays, it would be more efficient just to swap the pointers to the arrays. I was always under the impression that array names were essentially just pointers, but the following code receives a compiler error:

double left[] = {1,2,3};
double right[] = {9,8,7};

double * swap = left;
left = right; // Error "ISO C++ forbids assignment of arrays"
right = swap; // Error "incompatible types in assignment of `double*' to `double[((unsigned int)((int)numParameters))]'"

Creating the arrays dynamically would solve the problem, but can't be done in my application. How do I make this work?

A: 

Try this

double *right = (double[]){9,8,7};
double *left = (double[]){8,2,3};   
Charles Ma
I can't change the way the arrays were created; they're passed to the function I'm creating and I can't edit the way they were defined.
thornate
+3  A: 
double array_one[] = {1,2,3};
double array_two[] = {9,8,7};

double *left = array_one;
double *right = array_two;

double * swap = left;
left = right;
right = swap;

Works nicely.

edit: The definitions array_one and array_two shouldn't be used and the double*left and double*right should be as public as your original left and right definitions.

Daniel
It does seem to work nicely.
WarmWaffles
It only works nicely if I want to use left and right after that point; I actually need to swap array_one and array_two, so that they're also swapped in the function that called this one.
thornate
@thornate there's no function in your question example. Maybe it could be solved by passing pointers to a function? But it would be better if you could edit your post and explain what exactly you are trying to accomplish.
doc
A: 

C-style arrays are not pointers, but like most objects, they can be swapped with the standard std::swap():

#include <iostream>
#include <utility>
int main()
{
        double array_one[] = {1,2,3};
        double array_two[] = {9,8,7};
        std::swap(array_one, array_two);
        std::cout << "array_one[0] = " << array_one[0] << '\n';
        std::cout << "array_two[0] = " << array_two[0] << '\n';
}

Actually, looks like std::swap() for arrays is only defined in C++0x (20.3.2), so nevermind. The correct answer is, for both arrays in scope and arrays as pointers to first elements:

 std::swap_ranges(array_one, array_one + 3, array_two);
Cubbi
A: 

When you declare an array, the name is a pointer, which cannot be altered.

Ex:

int array[10];
int *p;

p = array; // legal
array = p; // illegal; array is a constant pointer which can't be altered.

The only way you can achieve the swap is using new pointers to the array.

This should help you:

SO question on array name as pointer

Kedar
`sizeof(array)` will prove that `array` is not a pointer. But it converts into a pointer when you need one.
MSalters
+3  A: 

Arrays are not the same as pointers and cannot be swapped in the way you describe. To do the pointer swap trick, you must use pointers, either dynamically allocate the memory, or use pointers to access the data (in the way Daniel has described).

5ound
Arrays are not pointers. Arrays are not pointers. Arrays are not pointers. +1
xtofl
Speaking of dynamically allocating the memory, you could use std::vector, which has a `swap()` method for swapping the underlying pointers.
JWWalker
A: 

You can pass both pointers to arrays by references, and in case pointers are not const, you can just swap them:

void swap(char * & first, char * & second)
{
     std::swap(first, second);
}
UnknownGosu
A: 

One of the easiest ways to convince people that they're not pointers, and not easily swapped, is to show the following code:

struct ex {
  char c[4];
  double d[3];
};
struct ex a = {"foo", {1.0, 2.0, 3.0} };
struct ex b = {"bar", {6,7,8} };

Now clearly a.d and b.d are arrays. Swapping them will involve hard work, as the array {6,7,8} has to end in memory after a.c=="foo" and that means copying 3 doubles. There's no pointer in the picture.

MSalters