tags:

views:

139

answers:

9

I am trying to return a simple array, but I am not getting the correct result. I am getting the following

arr1[0] = 1 
arr1[1] = 32767

result while the result should have been

  arr1[0] = 1 
  arr1[1] = 15

Please suggest.

int *sum(int a, int b){
  int arr[2];
  int *a1;
  int result = a+b;
  arr[0]= 1;
  arr[1]= result;
  a1 = arr;
  return a1;
}
int main(){  

  int *arr1 =  sum(5,10);
  cout<<"arr1[0] = "<<arr1[0]<<endl;
  cout<<"arr1[1] = "<<arr1[1]<<endl;

  return 0;

}
+5  A: 

a1 is a local variable, allocated memory on stack. If you want to return int *, you should allocate memory on the heap.

int *arr = (int *)malloc(sizeof(int) * 2));

//CAUTION you need to de-allocate memory [read about free()]

Explanation:

See arr is actually an array as long as the function int *sum(int, int) does not complete. SO, what you return is actually the address where arr actually was, and is no longer there.

When, you try to access that memory location in main(), you just get garbage/random values.

N 1.1
Be aware that the caller then has to delete the array, or a new memory-leak is born.
Space_C0wb0y
IMO I think OP is quite new to C/C++, cannot explain him all the details in one post :).
N 1.1
`When, you try to access that memory location in main(), you just get garbage/random values`What you get is undefined behavior, and garbage values are not the worst thing that can happen.
Space_C0wb0y
+15  A: 

You can't return arrays. All you are returning is a pointer to a local object which is destroyed when it goes out of scope as the function returns.

You can pass in a pointer to the array, so the array is modified by the function.

Also, you can return a copy of an array if it is wrapped inside a struct/class, such as std::tr1::array (or boost::array).

UncleBens
There is of course the possibility of returning a pointer to a heap-allocated array. The caller would then be responsible for deleting it.
Space_C0wb0y
yes, you can, as Sapce_C0wb0y said, but it is really bad practice because the user of your function in most cases will not read your policy to deallocate the memory and it will leak
m_pGladiator
You could make it harder for the user to screw up by returning a smart pointer, but it'd have to be one that handles arrays properly (uses delete []). Boost has shared_array for things like this. But I'd sooner use a vector or other standard container.
Fred Larson
I'd definitely not return a pointer to a dynamically allocated array. In this particular case, returning a pair like gf suggests might make more sense. (Actually, since the first value is always going to be one, why not just return the sum ... in which case the function is hardly needed in the first place.)
UncleBens
A: 

It is wrong to return a pointer to a locally defined array. a1 is placed on the stack, which gets cleaned when the function returns. Therefore you are no longer allowed to access that memory.

To "return an array" you can dynamically allocate it with new and then return it. Keep in mind that this will force you to free it later, so you'll have to carefully design the memory management policy for that array.

Eli Bendersky
+1  A: 

it is very wrong. int arr[2]; is local variable and lives in stack frame. you can't return pointers to stack from function. they become invalid.

Andrey
A: 

arr is on the stack - once you return from sum(), it no longer exists. A pointer to it might return random data, which is what you're seeing when you return a1.

Graham Lee
+1  A: 

Hmm.. well, arr is a stack variable and you're returning a pointer to it and expecting it to still be valid.

itsmatt
A: 

You should allocate a memory for the arr first, so it is not a stack variable. Then somebody outside your function should free it. It is better if you pass arr as a parameter to the function, so you can allocate and deallocate memory for it in one and the same abstraction level.

m_pGladiator
+5  A: 

You are returning a pointer to a local variable - when sum() has returned to main() the array isn't around anymore.

You can't even return arrays by value unless you wrap them, but you could simply return a standard container like std::vector or a std::pair:

std::pair<int,int> f(int a, int b) {
    return std::make_pair(1, a+b);
}

int main() {
    std::pair<int,int> res = f(5,10);
    std::cout << res.first << ", " << res.second << std::endl;
}
Georg Fritzsche
+7  A: 

Try this...


#include <vector>
#include <iostream>

std::vector<int> sum(int a, int b)
{ 
  std::vector<int> rv(2);
  rv[0]= 1; 
  rv[1]= a+b; 
  return rv; 
} 

int main()
{   
  std::vector<int> arr1 = sum(5,10); 
  std::cout << "arr1[0] = " << arr1[0] << std::endl; 
  std::cout << "arr1[1] = " << arr1[1] << std::endl; 

  return 0; 
} 

andand