Reputation: 49
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?
Upvotes: 1
Views: 3899
Reputation: 3744
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.
Upvotes: 1
Reputation: 586
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.
Upvotes: 0
Reputation: 3887
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.
Upvotes: 1
Reputation: 393
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.
Upvotes: 0