tags:

views:

278

answers:

7

Why does the following code not work?

It compiles fine but output is something like an address if I write f using * and the output is 0 if I write f without *.

#include <iostream>
#include<cstring>
using namespace std;
using std::size_t;
int *f(size_t s){
    int *ret=new int[s];
     for (size_t a=0;a<s;a++)
          ret[a]=a;
      return ret;
      }
int main(){

    size_t s=20;
    cout<<*f(s)<<endl;

    return 0;
}
A: 

The best way to get an array out of a function is by giving a reference to it as an input argument (i.e. pass in a pointer to the start of the array), then once your function is complete, the array you passed in will have been populated by the function. I wouldn't advise even trying to return one.

An alternative is something like the STL Vector (http://www.cplusplus.com/reference/stl/vector/) class or similar variants, which can be returned, but it really depends on what you intend to use it for.

ianhales
That's a dynamically allocated array. The code should work fine the way it is.
sbi
I was always taught it was bad practice to return an array created in a function. That just seems a bit messy.
ianhales
Ahh, I see what you mean now. OK, yeah, upvoting codaddict.
ianhales
+2  A: 

f(s) returns an int* so *f(s) is an int (the 1st item of the allocated array) with the value of 0. That's what it should appear, just a 0

frag
A: 

You can't use the << operator to output an array. You have to create a for loop and print each entry.

Save the output of f to a variable and print each entry.

Starkey
+11  A: 

You're using C++, simply use std::vector instead, it simplifies everything :

#include <iostream>
#include <vector>

std::vector<int> f(size_t s){
    std::vector<int> ret( s );
     for (std::size_t a=0;a<s;a++)
          ret[a]=a;
      return ret;
      }
int main(){

    std::size_t s = 20;
    std::vector<int> v = f(s);
    for( std::vector<int>::iterator it = v.begin(); it != v.end(); ++it ) // go through each element
        std::cout<< *it << std::endl;

    for( int idx = 0; idx != v.size(); ++idx ) // simpler variant that is equivalent in this example
        std::cout<< v[idx] << std::endl;


    return 0;
}
Klaim
This misses a few `std::` prefixes. Nevertheless, `+1` from me. This is the only sane option for newbies.
sbi
Ah yes, forgot to fix this after copy-pasting the code from the question...should be fixed now.
Klaim
+1 from me as well, however, many times it is a requirement of a homework assignment to not touch standard containers - speaking from experience.
Samaursa
I didn't assume it was a homework, only thought the asker was searching a way to return "arrays" from functions.
Klaim
+11  A: 

The function f(s) returns the address of the dynamically allocated array.

If you do cout<<f(s)<<endl; it will print that address and if you do cout<<*f(s)<<endl; it prints the value at index 0 which is 0.

If you want to print the entire array, run a loop as:

int *p = f(s);
for (size_t a=0;a<s;a++) {
    cout<<*(p+a)<<endl;
}
codaddict
+2  A: 

It is easier to understand it when the code is separated into 2 lines:

int* ret = f(s);
cout<<*ret<<endl;

*ret == ret[0] == 0. Because of that it prints 0 for the code you posted.

*Note that you are allocating an array (using new) but never deallocating it.

If your intention is to print all the elements in the array, you can use the following code:

size_t s=20; 
int* ret = f(s);
for (size_t i = 0; i < s; i++)
    cout<< ret[i] << " ";
delete[] ret;
rursw1
`delete ret` is invoking undefined behavior, it should be `delete[] ret`.
FredOverflow
Thank you. Fixed the answer accordingly.
rursw1
+2  A: 

As @frag says, main() knows nothing about the type of f(s) except that it is a pointer to int. It doesn't have any reason to look for 19 other ints.

Your main function should look more like this:

int main(){

    size_t s=20;
    int *p = f(s);
    for (size_t i=0; i<s; i++)
      cout<<*(p+i)<<endl;

    return 0;
}
Dave Costa