0

I'm trying to reverse the sequence of an int-array. Here's my code which gives a truckload of errors.

#include <cstdlib>
#include <iostream>

using namespace std;

int [] reverseArray(int []);

int main(){
    int arr[5] = {3,9,11,2,7};
    int arr2[5] = reverseArray(arr);

    for (int i = 0; i < 5; ++i)
    {
        cout << arr2[i] << endl;
    }
}

int [] reverseArray(int param[]){
    int s = sizeof(param)/sizeof(param[0]);
    int j = 0;
    int* a[s];
    for (int i = s ; i >= 0; i--)
    {
        a[j] = param[i];
        j++;    
    }
    return a;
}

I need to pass the modified array back to the main function. So please don't suggest me void functions that handles the output themselves.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
Ankur
  • 73
  • 1
  • 11
  • 5
    **fyi**, there's also an [`std::reverse`](http://en.cppreference.com/w/cpp/algorithm/reverse) in the standard library. – oblitum Nov 12 '14 at 22:36
  • They're two very different questions as I see. – Ankur Nov 12 '14 at 22:37
  • @pepper_chico, I'm aware of that. But I'm trying to get the logic myself. – Ankur Nov 12 '14 at 22:37
  • Don't return arrays from functions like that. C arrays are not your friend. Modifying `param` is sufficient to alter the original array. If you want arrays to behave like normal objects, use `std::array` or `std::vector` – Neil Kirk Nov 12 '14 at 22:37
  • 2
    Printing the value of `s` ( in `int s = sizeof(param)/sizeof(param[0]);`) might give you a clue. – P.P Nov 12 '14 at 22:38
  • 2
    They are not two very different questions. your array decays when you pass it as a parameter. `sizeof(param)` does not do what you think it does. – Red Alert Nov 12 '14 at 22:39
  • Can someone please provide the correct implementation of the code. – Ankur Nov 12 '14 at 22:40
  • @SoumasishGoswami the cppreference.com link that was provided has a "possible implementation" section that should work. Maybe you could try to understand what it is doing. – Tim Seguine Nov 12 '14 at 22:40
  • you need to allocate space for the array on the heap (e.g. malloc). You can't return a local array, as it will have gone out of scope when the function returns – The Archetypal Paul Nov 12 '14 at 22:46
  • @Paul I don't think "use malloc" is good advice here.. – Neil Kirk Nov 12 '14 at 22:48
  • @NeilKirk given the constraints of the questioner their aren't really other options, since the OP is dead set against `std::vector` and specifically doesn't want to use output parameters. – Tim Seguine Nov 12 '14 at 22:52
  • @Paul or Neil can either of you modify my existing code and provide a working implementation, with a few words explaining why you did it that way. – Ankur Nov 12 '14 at 22:53
  • @Paul Since he's using c++, I think the better advice is to use `std::array`. Its purpose is to be an array that can be passed/returned without issue, which it looks like OP wants. – Red Alert Nov 12 '14 at 22:54
  • 1
    This is not a duplicate of "What is array decaying". Yeah, OP doesn't know about array decaying, but that is not the question nor the answer. – M.M Nov 12 '14 at 23:18
  • 1
    @NeilKirk, I assumed this was an assignment. If there's a need to actually reverse an array in production code, then yes, `std:vector` or something is a better choice – The Archetypal Paul Nov 13 '14 at 07:18

5 Answers5

2

Here is an implementation using std::array class which works more like you expect. The reverse function is able to take arrays of any size and type, provided the length is known at compile-time. I also fixed a bug in your reverse logic. It went out of bounds on the param array on the first iteration.

Live example here: http://ideone.com/UuUQ9c

#include <iostream>
#include <array>
using namespace std;

template<class T, size_t N>
std::array<T, N> reverseArray(const std::array<T, N>& param)
{
    int j = 0;
    std::array<T, N> a;
    for (int i = N - 1 ; i >= 0; i--)
    {
        a[j] = param[i];
        j++;    
    }
    return a;
}

int main()
{
    std::array<int, 5> arr = {3,9,11,2,7};
    std::array<int, 5> arr2 = reverseArray<int, 5>(arr);

    for (int i = 0; i < 5; ++i)
    {
        cout << arr2[i] << endl;
    }
}
Neil Kirk
  • 21,327
  • 9
  • 53
  • 91
  • 2
    +1, though I'd prefer `auto arr2 = reverseArray(arr);` to reduce maintenance if the length of `arr` ever changes. – Red Alert Nov 12 '14 at 23:27
  • @RedAlert Good comment. I wanted to keep it straight forward. The repetition of the template parameters is not the best. – Neil Kirk Nov 12 '14 at 23:27
1

If you are using C++ you can simplify your solution with:

    vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);
    reverse(v.begin(),v.end());
    for(auto& e : v)
      cout << e << " ";

http://ideone.com/mDMSmZ

dynamic
  • 46,985
  • 55
  • 154
  • 231
  • I don't want to use vectors, can you please implement the code using C-Style arrays. – Ankur Nov 12 '14 at 22:43
  • 1
    @SoumasishGoswami vectors are just as fast as arrays most of the time, and they are less error prone. Why do you want to use arrays? – Tim Seguine Nov 12 '14 at 22:44
  • 1
    probably the teacher said to do so. – ash Nov 12 '14 at 22:44
  • @ash teaching beginners arrays first is just bad teaching. – Tim Seguine Nov 12 '14 at 22:45
  • 1
    @TimSeguine I wouldn't necessarily agree. Either way, this smells like homework to me. – ash Nov 12 '14 at 22:47
  • Guys, homework or not, thing is I need a correct implementation, with some explanation as to how arrays are passed between functions in C/C++. Great if you can provide that, if not, stop your time and mine. – Ankur Nov 12 '14 at 22:51
1

Without using the std library:

Using simply int[] type and without dynamic allocation you can't have it as return value, because the size of resulting int[] is unknown at compilation type. You can still do the following, obtaining the same result:

void reverse(const int a[], int size, int arr[]){
   int tmp, i;
   for (i=0; i < size; i++){
      arr[i]=a[i];
   }
   for (i = 0; i < size/2; ++i) {
      tmp = arr[size-i-1];
      arr[size-i-1] = arr[i];
      arr[i] = tmp;
   }
}

int main(){
   int size=5;
   int source[] = {3,9,11,2,7};
   int destination[size];
   reverse(source, size, destination);
}

Using the std library (recommended):

If available and if not in special conditions (e.g. some homework/assignment constraint ;) ) you should prefer std library algorithms:

int a[]= {...};
const int size = sizeof(a)/sizeof(int);
int b[size];

std::reverse_copy(a, a+size, b);
Alex Gidan
  • 2,619
  • 17
  • 29
1

No such as thing return type int[], because unknown size variable can't be located on stack.

Your options are:

const int* reverse(const int input[],size_t size){
   int* output = new int[size];//needed to be delete 
   ...
   return output;
}  

void reverse(int input_output[],size_t size){
   //use same array for input & output 
}  

void reverse(const int input[], int output[],size_t size){
   //get output as out parameter 
}  

Best options if you ask me are the 2nd and the 3rd, use the 2nd if you can change the input, use the 3rd if you need both input and output.

SHR
  • 7,940
  • 9
  • 38
  • 57
0

I tried to apply minimal changes to your code. Here is something that worked:

#include <cstdlib>
#include <iostream>

using namespace std;

int * reverseArray(int, int []);

int main(){

    int arr[5] = {3,9,11,2,7};
    int sz = sizeof ( arr ) / sizeof ( arr[0] );
    int * arr2 = reverseArray(sz, arr);

    for (int i = 0; i < 5; ++i)
    {
        cout << arr2[i] << endl;
    }


}

int * reverseArray(int s, int param[]){

    int j = 0;
    int * a = new int[s];
    for (int i = s - 1 ; i >= 0; i--)
    {
        a[j] = param[i];
        j++;
    }

    return a;
}

Explanation:

  • The array is passed to function by pointer. So, you cannot determine its size in there. You will have to determine the size beforehand and pass the size with as a function parameter.
  • The way you allocated array is local to the function. You need to allocate dynamic memory to be able to pass it back.
unxnut
  • 8,509
  • 3
  • 27
  • 41
  • 1
    What about the memory leak? – Neil Kirk Nov 12 '14 at 22:57
  • This code really helps, let me understand this right. So in the function reverseArray you're returning a pointer to the array a? – Ankur Nov 12 '14 at 23:01
  • `a` points to an array allocated on the heap. A copy of this pointer is returned from the function. The pointer `a` and the array it points to are separate entities. – Neil Kirk Nov 12 '14 at 23:04
  • @NeilKirk just out of curiosity are we not supposed to delete all variables created using new – Ankur Nov 12 '14 at 23:08
  • Yes that's why I discourage any code with `new` in it. – Neil Kirk Nov 12 '14 at 23:09
  • So is there any other way this can be done, without using from STL. If we assume this was a C Program. – Ankur Nov 12 '14 at 23:10
  • Any good ways with the constraints you specify? No. – Neil Kirk Nov 12 '14 at 23:13
  • @SoumasishGoswami, without using dynamic allocation quick answer: no. the best you can do is an input/output parameter as per my solution. – Alex Gidan Nov 12 '14 at 23:14
  • You could use `void reverseArray(int s, const int input[], int output[])` which would remove the need for dynamic memory. – Neil Kirk Nov 12 '14 at 23:15
  • Yes, this code does leak memory and I had noticed that when I wrote it. However, as the code terminates quickly, I did not bother to add `delete`. There are other things I would have liked to do, for example, using a single variable in the loop instead of `i` and `j` but I tried to stay close to OP's code. – unxnut Nov 12 '14 at 23:59