15

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?

thornate
  • 4,902
  • 9
  • 39
  • 43
  • Array name is not a pointer. Array name is an address of its first element. – mip Aug 03 '10 at 04:17
  • 1
    Whereas a pointer is an address to a variable. Why can't I swap those addresses? – thornate Aug 03 '10 at 04:29
  • 2
    @thornate: The most relevant difference between an array name and a pointer variable is that an array name is not an lvalue, therefore it cannot be the target of an assignment statement. So the way to do what you want is to assign the array names to pointer variables, which _are_ lvalues, then swap those. There's no way to make "left" or "right" point to anything else, once they've been defined. – Jim Lewis Aug 03 '10 at 04:37
  • @thornate pointer's *value* is an address to the variable. The pointer name itself does not denote address like in the case of arrays (you have to use operator `&` to get the addresss of a pointer). During pointer assignments one pointer's *value* is taken and assigned to another pointer. You can't do that on arrays because, by the language concept, they denote adresses itself. According to this, you are trying to do something like `0x23ff10 = 0x23ff44` assuming that left is `0x23ff10` and right is `0x23ff44`. – mip Aug 03 '10 at 09:57
  • @thornate: "I have two arrays of pointers to doubles"??? Where? You don't have any "arrays of pointers" in your code. – AnT stands with Russia Aug 03 '10 at 14:50
  • @AndreyT: True. My real code was too long and complex to post. The code above was just an example of what I meant. I suppose I should have been clearer about that. – thornate Aug 16 '10 at 13:38
  • By swapping do you mean the corresponding array values should get swapped or address of left and address of right should get swapped? – sameerkn Sep 18 '17 at 06:43

7 Answers7

14
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.

knittl
  • 246,190
  • 53
  • 318
  • 364
Daniel
  • 1,994
  • 15
  • 36
  • 1
    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 Aug 03 '10 at 04:23
  • @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. – mip Aug 03 '10 at 16:21
  • It doesn't always seem to work. std::swap() is a much better option in C++. – Preetom Saha Arko Sep 08 '17 at 08:05
13

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
  • 1,179
  • 6
  • 9
  • 14
    Arrays are not pointers. Arrays are not pointers. Arrays are not pointers. +1 – xtofl Aug 03 '10 at 05:09
  • 1
    Speaking of dynamically allocating the memory, you could use std::vector, which has a `swap()` method for swapping the underlying pointers. – JWWalker Aug 03 '10 at 05:11
5

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
  • 46,567
  • 13
  • 103
  • 169
2

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
  • 173,980
  • 10
  • 155
  • 350
0

Try this

double *right = (double[]){9,8,7};
double *left = (double[]){8,2,3};   
Charles Ma
  • 47,141
  • 22
  • 87
  • 101
  • 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 Aug 03 '10 at 04:24
  • 1
    This syntax is a C99 feature which is not in C++ – M.M Jan 19 '16 at 00:10
-1

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
  • 854
  • 6
  • 9
-2

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

Community
  • 1
  • 1
KedarX
  • 763
  • 1
  • 7
  • 15
  • `sizeof(array)` will prove that `array` is not a pointer. But it converts into a pointer when you need one. – MSalters Aug 03 '10 at 14:44