0

When passed into a function as a parameter, only a pointer to the first element of the array is passed. I've found a temporary workaround:

int function(int array[], int size) {
   int otherArray[50]; // high enough number

   for (int i = 0; i < size; i++) {
       otherArray[i] = array[i];
   }

   // use otherArray
}

Is there a more efficient and concise way of passing in the whole array? This seems horribly inefficient.

EDIT: Solved by using std::vector for my data, and using &vec[0] to retrieve the array.

Stefan Ivanovski
  • 117
  • 2
  • 10
  • 4
    use `std::vector` – Brian Bi Jul 30 '18 at 21:25
  • 1
    what problem you're trying to solve? why are you copying input array? – Iłya Bursov Jul 30 '18 at 21:26
  • 3
    When you call a function with an array you get a pointer to the array. ([What is array decaying?](https://stackoverflow.com/questions/1461432/what-is-array-decaying)) It's really hard to pass an array by value. If you have to work on a copy of an array, use a `std::vector` or a `std::array` because they can ba passed by value. If you don't need to work on a copy, just use the pointer and don't make a copy. – user4581301 Jul 30 '18 at 21:28
  • 2
    Use `std::array` or `std::vector`. *Not* C-style arrays, please. – Jesper Juhl Jul 30 '18 at 21:32
  • ***Is there a more efficient and concise way of passing in the whole array?*** I assume you are not permitted to use `std::vector` or `std::array` and that is the motivation for this question. Is that correct? – drescherjm Jul 30 '18 at 21:32
  • I don think it passes the whole array here. It just passes a pointer to the very first item of the array. So, this should be fine. – stdout Jul 30 '18 at 21:32
  • @Brian I need to reuse the data from the array. So I would need to convert the vector to an array once again. – Stefan Ivanovski Jul 30 '18 at 21:42
  • @user4581301 I'll look into this. Thanks – Stefan Ivanovski Jul 30 '18 at 21:43
  • 2
    " need to reuse the data from the array. So I would need to convert the vector to an array once again." I don't see how reusing data implies a requirement to convert a vector to an array. – Jerry Coffin Jul 30 '18 at 21:49
  • More information about your use case and what you have at your disposal at the time of the call will allow us to give better-targeted answers rather than just making suggestions. – user4581301 Jul 30 '18 at 21:49
  • @JerryCoffin I'm using an OpenGL call 'glBufferData' which requires a 'const void* data' parameter. I'm passing in the vertices of an object. – Stefan Ivanovski Jul 30 '18 at 21:51
  • @user4581301 View the answer above ^ – Stefan Ivanovski Jul 30 '18 at 21:52
  • For example, if you read data into an array, you can just as easily (more easily a lot of the time) read into a `vector`. If you call a function with your array, and that function fills your array with data, you can pass the function a pointer to the `vector`'s internal buffer with the `std::vector::data` method (if your compiler's up do date) or a pointer with `&vec[0]` (technically dodgy, but works in every case I've encountered so far). – user4581301 Jul 30 '18 at 21:53
  • In that case, you can pass `&your_vect[0]` (among other possibilities). `std::vector` guarantees contiguous allocations, so you're still passing the address of a block of memory that looks like a C array. – Jerry Coffin Jul 30 '18 at 21:53
  • 1
    @Stefan Ivanovski `std:: vector` has a `.data()` member function that should be fine for passing to your OpenGL function expecting a C-style array. – Jesper Juhl Jul 30 '18 at 21:54
  • Why do you need to copy the array in order to use the data? Just do the calculations on the original array and (if necessary) store the results in a temporary local array. – Spoonless Jul 30 '18 at 21:55
  • What happens if 'size' is greater than 50? – Spoonless Jul 30 '18 at 21:55
  • There is *nothing* you can do with your *array* that can't be done using a `std::vector` because a `std::vector` is just a wrapper round an *array*. You can get at the internal array using `my_vector.data()`. – Galik Jul 30 '18 at 21:59
  • @JerryCoffin &vec[0] worked. Thanks to everyone that replied. – Stefan Ivanovski Jul 30 '18 at 22:17
  • @Galik Yes, this works also. Thank you :) – Stefan Ivanovski Jul 30 '18 at 22:20
  • @user4581301 Both methods work. Thank you – Stefan Ivanovski Jul 30 '18 at 22:21

2 Answers2

0

You cannot pass an array to a function. You have options to approximate it:

  • reference to a raw array
  • std::array
  • std::vector

For maximum efficiency, you do not want to copy an array. That's why arrays decay to pointers in the first place (though it was inherited from C and there are better ways to accomplish the same or similar behavior that is more type-safe.) If you want to keep the type without decay, you must pass a reference to the array, or to an object containing such an array.

// pass reference to a raw array (Array of N elements of type T)
template <typename T, int N>
void foo1(T(&arrayArg)[N])
{
   std::cout << arrayArg[0] << "\n";
}

Given the code you initially used in your question, I suspect the above is what you were looking for. However consider the alternatives too, because arrays are not a very robust data type in c++ and there are better options for general code.

// pass reference to std::array
template <typename T, int N>
void foo2(std::array<N, T> const & arrayArg)
{
   std::cout << arrayArg[0] << "\n";
}

The std::array is a class that contains a raw array underneath, but has more of a C++ friendly interface and is not subject to decaying.

// pass reference to std::vector
template <typename T>  
void foo2(std::vector<T> const & vecArg)
{
   std::cout << vecArg[0] << "\n";
}

Vector is dynamically sized, and is getting farther away from the raw array you started with, but is the building block of many, many c++ data structures and algorithms and should be one of the first things you consider in most cases.

Chris Uzdavinis
  • 4,167
  • 4
  • 14
  • Good run-down, but misses out on the asker seemingly wanting to pass by value and get the copy. Why they want that, ehhhhhh... We don't quite know that yet. It could be a bad idea, could be exactly what they want. No way to tell. – user4581301 Jul 30 '18 at 22:05
  • It's kind of ridiculous to want a full copy and simultaneous worry about it being inefficient. Either copy and be slow (the longer the array, the slower), or don't copy and be efficient. That's just the reality of arrays. Since OP didn't like copying, I answered on the assumption it was to be efficient without losing the type info. – Chris Uzdavinis Jul 30 '18 at 22:11
  • 1
    Not going to argue that. The answer to the question could very well be, "Don't copy." But if the asker has to copy, for backtracking or whatever, the answer is "Maybe you'll get better performance from using a smarter data structure or `std::copy`." – user4581301 Jul 30 '18 at 22:17
-1

There is one historical method for passing an array by value to the function using structures, fortunately in c++ you have collections like std::array, that can be passed by value.

You can read more about C way here.

proximab
  • 667
  • 8
  • 14
  • This question is tagged with C++ rather than C, so expect a bumpy road ahead. – user4581301 Jul 30 '18 at 21:42
  • @user4581301 what's the difference? OP wanted to know is it possible to pass an array by value, yes it is and this method was used since c, but of course in c++ nobody will even think about this, because there are many other containers like std::vector because they can be passed by value. Again OP asked about int array[]. Stop downvoting for no real purpose. – proximab Jul 30 '18 at 21:52
  • 2
    This is basically what `std::array` does, but it does it with bells ***and*** whistles. – Galik Jul 30 '18 at 21:52