1
struct zone {
  int a;
  double b;
};
zone *abc() {
  static zone r[10];
  for (int i = 0; i < 10; i++) {
    r[i].a = 2 * i;
    [r[i].b=0.5*i;
    cout << r[i].a << " " << r[i].b << endl;
  }
  return r;
}

int main() {
  zone *PP;
  zone P[10];
  PP = abc();
  for (int i = 0; i < 10; i++) {
    P[i] = (PP + i);

    cout << "work" << P[i].a << endl;
  }
  getch();
}

I need to return an array of structs that is formed in a function called by main. I managed to retrieve an array with a pointer, but with struct it doesn't work.

How do I return a struct array?

3
  • Certainly [r[i].b=0.5*i; should be r[i].b=0.5*i; (likely minor typo).) Commented Jul 16, 2015 at 14:57
  • P[i] = (PP + i); is a problem. I would expect P[i] = *(PP + i); (Add *) This may explain "but with struct it doesn't work" Commented Jul 16, 2015 at 14:59
  • "isn't working". Out of cheese or divide by cucumber? Commented Jul 16, 2015 at 15:46

4 Answers 4

1

You are assigning a value of variable with a pointer:

P[i] = (PP + i);

To get a copy of internal value, you need access struct:

P[i] = PP[i];

Would be like this:

#include <iostream>
using namespace std;

struct zone {
  int a;
  double b;
};

zone *abc() {
   static zone r[10];
   for (int i = 0; i < 10; i++) {
       r[i].a = 2 * i;
       r[i].b=0.5*i;
       cout << r[i].a << " " << r[i].b << endl;
   }
   return r;
}

int main() {
    zone *PP;
    zone P[10];
    PP = abc();
    for (int i = 0; i < 10; i++) {
        P[i] = PP[i];

        cout << "work" << P[i].a << endl;
    }
}

Your struct contains just digits, however, if it contains strings or pointer, you will need make a deep copy.

Sign up to request clarification or add additional context in comments.

1 Comment

I have one more question. what do u mean by deep copy. the struct will consist of int, double and boolean.
1

Well fairly simple - by using another struct to encapsulate the returned array in order to get over 'C' language limitations.

struct zone {
  int a;
  double b;
};

struct zone_array_of_10 {
  zone arr[10];
};

zone_array_of_10 abc() {
  zone_array_of_10 r;
  for (int i = 0; i < 10; i++) {
    r.arr[i].a = 2 * i;
    r.arr[i].b=0.5*i;
    cout << r.arr[i].a << " " << r.arr[i].b << endl;
  }
  return r;
}

int main() {
  zone_array_of_10 PP;

  PP = abc();
  for (int i = 0; i < 10; i++) {

    cout << "work" << PP.arr[i].a << endl;
  }
  getch();
}

It's fact that in 'C' language arrays can't be passed by value. However structures can. So whenever you want to pass the actual content of some array without much hassle - just encapsulate it in a structure.

Comments

0

A cool feature of C++ is the use of references. The best part of references is that they allow you to pass data in an out of a function without copying the data (you are using the same data inside and pass back out). So if you make a function.

Another method is to use a pointer to a pointer. You can pass a pointer pointer or address of a pointer and malloc within the function.

structure* a;
funct(&a);
printf("%s\n", a[0].printfunction());
printf("%s\n", a[1].printfunction());
...

void funct(structure** a, int size){
*a = (structure*)malloc(sizeof(structure) * size);
(*a)[0] = ...
(*a)[1] = ..
(*a)[ size-1] = ...
}

You can access the array outside of the function. Just be sure to free/delete anything you call with malloc/new. The above code can use new I'm just better with c. You can easily pull the malloc outside of the function and just pass in a pointer to the array.

5 Comments

Why use malloc in C++?
We do what we must because we can? I wrote C friendly code since the only aspect of c++ the OP used was cout and endl.
While malloc has its uses in C++ code, new and free should be used instead as a general rule when memory must be allocated, but for better C++, use standard containers where possible and smart pointers when not.
new and delete or new and free?
Oops :) new and delete (as well as new[] and delete []).
0

In C, a function can't take or return an array. This is annoying, and I've never heard a good reason given for it. Anyway, C++ fixed this a long time ago, but it never really caught on, for reasons that will become plain in a moment.

Obligatory "for anything larger than a toy application you should strongly reconsider using naked pointers and/or raw arrays!"

C++ introduced references. They are really just syntactic sugar around pointers, but aren't all variables just syntactic sugar around pointers? In C++, a function can take and/or return a reference to an array. Like so:

int takes (char (&arr)[10])
{
    std::cout << sizeof(arr); // 10
}

int (&returns())[10]
{
    return some_array; // Not a pointer!
}

int (&takes_and_returns (int (&arr)[10])) [10]
{
    return arr;
}

Of course, I don't have to tell you that this is extremely ugly and difficult to read. Modern C++ to the rescue!

template <size_t n, typename T>
using array<n,t> = T[n];

int takes (array<10,int>& arr);

array<10,int>& returns();

array<10,int>& takes_and_returns (array<10,int>& arr);

Note, however, that due to the way new works, it is an ordeal to properly construct and then return a reference to a dynamic array. This is how I did it, but I'm not even sure if this is correct; there might lurk some UB:

int (&returns())[10]
{
    int* x = new int[10];
    return *(int(*)[10]) x;
}

Of course, we can tidy this up a bit:

using arr10 = int[10];

arr10& returns()
{
    int* x = new int[10];
    return *(arr10*) x;
}

And then, at the call site, you'd assign it to a reference like so:

int (&my_array)[10] = returns();
// doing stuff ...
delete[] &my_array;

As you can see, at the end of the day, getting all this to work correctly and to interoperate with existing features is a bit of an ordeal. If you need a function to take or return an array, this is how you do it. But for most purposes, it is better (easier, safer) to use standard library containers.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.