6

I need to read in an array to my function, extract the data, and then return an array from the function.

The array will only ever hold 2 values.

This is what I want to do in concept:

int myfunction(int my_array[1])
{
    int f_array[1];
    f_array[0] = my_array[0];
    f_array[1] = my_array[1];

    // modify f_array some more

    return f_array;
}

I've read up about pointers etc but have got very confused and would appreciate a really basic example of how best to approach this!

Thanks!

Shahbaz
  • 46,337
  • 19
  • 116
  • 182
user1055774
  • 131
  • 1
  • 4
  • 9
  • @fefe: because you might want to avoid an unnecessary memory allocation. `std::array`, or a struct containing an array, would be more efficient if the size is known at compile time. – Mike Seymour Jan 05 '12 at 15:54
  • 5
    This particular array has room for only **one** item. An array stores as many items as it says, not one more than asked for. – UncleBens Jan 05 '12 at 15:54
  • Whatever way you choose to do this make sure you still learn pointers because they are a very important concept. – Mike Webb Jan 05 '12 at 15:56
  • 1
    To emphasize this UncleBens' point, when you are declaring an array, you declare the numbers of items it contains: in `int a[N]`, `a` is an array containing `N` elements. When then use indexes to refer to elements, you index from `0` to `N-1`. The address `a + N` exists, but it refers to one past the end of the array and no element lives there. It should not be accessed with `a[N]`, or daemons will fly out of your nose. – Matthieu M. Jan 05 '12 at 15:58

7 Answers7

9

You can't return n builtin array in c++.

If you are new to c++ and get confused about pointers you really don't want to use arrays (at least not builtin arrays). Use std::vector<int> instead, or if you only ever have a certain number of elements and want to express that (and really need the better performance) use boost::array<int, N>.(or even std::array<int, N>, if you program in C++11 (if you don't know whether or not you program in C++11 chances are that you don't). For example:

std::vector<int> myfunction(const std::vector<int>& my_array) {
  std::vector<int> f_array;
  for(int i = 0; i < my_array.size(); ++i)
    f_array.push_back(my_array[i]);
  return f_array;
}

boost::array<int, 2> myfunction(const boost::array<int, 2>& my_array) {
  boost::array<int, 2> f_array;
  f_array[0] = my_array[0];
  f_array[1] = my_array[1];
  return f_array;
}

You can then make your copying code simpler (look up the constructors and memberfunctions of whatever class you decide to use, as well as STL algorithms). Example:

std::vector<int> myfunction(const std::vector<int>& my_array) {
  std::vector<int> f_array(m_array);
  ...
  return f_array;
}

As another point your code has a bug in it: you define my_array as int my_array[1], meaning its an array with one element, but you access two elements (my_array[0] and my_array[1]), the access to my_array[1] is out of bounds (int foo[N] has place for N items, starting at index 0 and going to index N-1). I assume you really mean int my_array[2].

Baum mit Augen
  • 49,044
  • 25
  • 144
  • 182
Grizzly
  • 19,595
  • 4
  • 60
  • 78
  • 1
    And if you have access to a current C++ compiler that implements the move-semantics from C++11, familiarise yourself with it as it will kill almost completely any performance overhead that comes with easy solutions like this. – filmor Jan 05 '12 at 15:49
  • 2
    @filmor: actually it might not make a difference, since (at least in such an easy example) the compiler can probably do **Named Return Value Optimization** and completely omit the copy (or move in C++11) anyways – Grizzly Jan 05 '12 at 15:54
7
std::array<int,2> myfunction(int * my_array)
{
    std::array<int,2> f_array;
    f_array[0] = my_array[0];
    f_array[1] = my_array[1];

    // modify f_array some more

    return f_array;
}

Note that as a parameter, int my_array[1] is exactly identical to int my_array[1000], int my_array[] or int * my_array. It's just a pointer, and the size value is meaningless. This doesn't apply to regular array declarations, just parameters.

To ensure that you're only being passed arrays of size 2, you can take the array by reference:

std::array<int,2> myfunction(int (&my_array)[2])
Benjamin Lindley
  • 101,917
  • 9
  • 204
  • 274
1

If you ever only need two values I would have a look at std::pair, after all, that's what it's there for. It also have the proper copy (move in c++11) semantics to make this work correctly.

harald
  • 5,976
  • 1
  • 24
  • 41
1

You can't return an array from a function, but you can add a second argument for the "out" array:

void foo(int array_in[], int array_out[], int array_size)
{
    for (int i = 0; i < array_size; i++)
        array_out[i] = array_in[i];
}
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
1

If you will have strictly 2 elements in array I suggest std::pair

typedef std::pair<int,int> int_pair;

int_pair myfunction(int_pair ip)
{
  ip.first *= 0.12;
  ip.second -= 355; 
  return ip;
}
ali_bahoo
  • 4,732
  • 6
  • 41
  • 63
0

You can't return an array in C or C++.

As you're working in C++, use a container class instead of a raw array. A std::vector or a boost::array would be good options.

Oliver Charlesworth
  • 267,707
  • 33
  • 569
  • 680
-1

An array with two values should be declared as int my_array[2]. Anyway, you can't copy arrays by value. You said you'll only ever have two ints in the object. So I suggest you use pair<int,int> instead.

using namespace std;
pair<int,int> myfunction(pair<int,int> my_array)
{
  pair<int,int> f_array;
  f_array.first = my_array.first;
  f_array.second = my_array.second;

  // modify f_array some more

  return f_array;
}
Aaron McDaid
  • 26,501
  • 9
  • 66
  • 88