8

Suppose I have an array

int arr[] = {...};
arr = function(arr);

I have the function as

 int& function(int arr[])
 {
//rest of the code
        return arr;
 }

What mistake am I making over here??

2
  • 2
    Why are you (or just any developer) writing this crazy code? :\ Commented Feb 20, 2010 at 14:22
  • @manugupt1: Is it your intent to pass the array into the function as a copy? Commented Feb 20, 2010 at 17:29

11 Answers 11

8
 int& function(int arr[])

In this function arr is a pointer, and there's no way to turn it back to an array again. It's the same as

int& function(int* arr)

int arr[] = {...};
arr = function(arr);

Assuming the function managed to return a reference to array, this still wouldn't work. You can't assign to an array. At best you could bind the result to a "reference of an array of X ints" (using a typedef because the syntax would get very ugly otherwise):

typedef int ten_ints[10];

ten_ints& foo(ten_ints& arr)
{
   //..
   return arr;
}

int main()
{
    int arr[10];
    ten_ints& arr_ref = foo(arr);
}

However, it is completely unclear what the code in your question is supposed to achieve. Any changes you make to the array in function will be visible to the caller, so there's no reason to try to return the array or assign it back to the original array.


If you want a fixed size array that you can assign to and pass by value (with the contents being copied), there's std::tr1::array (or boost::array). std::vector is also an option, but that is a dynamic array, so not an exact equivalent.

Sign up to request clarification or add additional context in comments.

Comments

8

As others said, there are better options like STL containers and the most interesting question is why you need to return the array to a function that already has it in scope.

That being said, you can't pass or return arrays by value and need to avoid the array decaying to a pointer (see e.g. here), either by using pointers or references to it:

int (&f(int (&arr)[3]))[3]
{
    return arr;
}

If you don't want to hard-code the size, you can use template functions:

template<size_t n>
int (&f(int (&arr)[n]))[n]
{
    return arr;
}

4 Comments

That is some seriously twisted syntax. You deserve lots of kudos for even getting it right here. I feel free to use typedefs now that I know how you could possibly have spelled that to the compiler without... +1
Assuming I would like to code a getter for a fixed size array and want the method as well as the referenced array to be const - how would I do that syntactically? Like this: int const (&GetArray() const)[ 3 ] { return mArray; }?
@Bjoern: typedef int A[3]; const A m; const A& f() const { return m; } ?
Thank you for actually posting the ugly syntax instead of just saying it's ugly and doing a typedef. A concrete example of this was very difficult to find
4

The semantics of array passing and return can be quite confusing. Use a std::vector instead.

4 Comments

or boost::array, if that's available.
While this is certainly good advice, it doesn't even remotely answer the question..
@Andreas "What mistake am I making over here??" - the mistake of not using a vector.
Which is obviously not what the OP meant by that question. With that reasoning I could answer with "The mistake of not indenting properly the comment in the second code snippet"..
3

You're returning a reference to an int, not a reference to an array.

You want :

(int*)& function(int arr[])
{
     /// rest of the code
     return arr;
}

That said, as others already said, that's not good practice.

1 Comment

Actually that returns a reference to a pointer and arr isn't an array either.
3

Following works and doesn't seem messy or mis-understandable!

int* returnarray(int a[])
{
    for (unsigned int i = 0; i < 3; i++)
    {
        a[i] *= 2;
    }
    return a;
}

int main(int argc, char* argv[])
{
    int arr[3] = {1,2,3};
    int* p = returnarray(arr);
    for (unsigned int i = 0; i < 3; i++)
    {
        cout << "p[" << i << "] = " << p[i] << endl; 
    }
        cin.get();
        return 0;
}

Comments

2

I think your best bet is to return it as a pointer to an array. Here is an example:

{
   ...
   int newLength = 0;
   int* arr2 = ChangeArray(arr, length, newLength);
   ...
   delete[] arr2;
}

int* ChangeArray(int arr[], int length, int& newLength)
{
   // reversing the number - just an example
   int* newArr = new int[length];
   for(int i = 0; i < length; i++)
   {
      newArr[i] = arr[length-i-1];
      newLength++;
   }
   return newArr;
}

Comments

1
  • An array as argument is actually a pointer. Arrays are automatically 'casted' to pointers if given as argument
  • You can't assign an array to another array in C/C++. You will have to use a memcpy or loop to copy the values.
  • If function changes the arr argument, it actually changes the value of the arr variable given by the caller. Again because the array is actually a pointer. So in the caller arr is assigned to arr, which is useless here.

Comments

0

Well, arr is compatible with int*, not int&. Your code won't compile. Perhaps you wanted return arr[0]?

Comments

0

You cannot assign an array to another array in C++. Consider using a STL vector: http://www.cplusplus.com/reference/stl/vector/

Comments

0

Use std:: vector like this.

std::vector<int> function(const std::vector<int>& arr)
{
  return arr;
}

An array like

int arr[] = {...};

is not useful to be returned from a function because its not able to copy itself.

Comments

0

if not necessary, don't use it. you can just pass a reference of an array, such as:

void foo(std::vector<int> &v) {
    for (int i = 0; i < 10; ++ i) {
        v.push_back(i);
    }
}

if you use:

std::vector<int> foo() {
    std::vector<int> v;
    for (int i = 0; i < 10; ++ i)
        v.push_back(i);

    return v;
}

there'll be a copy process of the container, the cost is expensive.

FYI: NRVO maybe eliminate the cost

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.