Reputation: 51
Ok so I have a struct listed as such:
typedef struct name
{
string thing1;
string thing2;
int thing3;
int thing4;
};
I use a function that runs through data and assigns everything into an array of structs establish the inside struct array. name structname;
function runs fine and assigns everything inside correctly...
structname[i].thing1 structname[i].thing2
etc. will cout fine inside the function
My question is how do I assign the function to return this array of structs? I can't seem to use pointers to do so and I have looked extensively on the web to find an answer.
EDIT: First off, first post here. always been using the resources, but i can't stress again how helpful in learning php, c++, etc. y'all have been.
I can pass structs into the function fine using a pointer, it's just returning an array of structs which seems to be the issue. My function is set up as a void so I have been using the void function(struct name &input) but that clearly doesn't seem to modify the struct. I have also tried to use the function as a return type but it mismatches as it is an array and not a struct.
Upvotes: 5
Views: 19274
Reputation: 1
That is true, that C++ doesn't recommend return arrays, but pointers to them, but! C++ allows everything. In particular:
#include "stdafx.h"
#include <iostream>
using namespace std;
typedef struct h{
int f[2];
};
h my(){
h a;
a.f[0]=1;
a.f[1]=2;
return a;
}
int _tmain(int argc, _TCHAR* argv[])
{
h j;
j=my();
cout << j.f[0];
system("pause");
return 0;
}
Upvotes: 0
Reputation: 29724
In C++ you would use std::vector:
std::vector<name> f(); // return by value
or
void f( std::vector<name>& v); // take by reference and assign to vector
// inside a function f
In C you cannot return array types. You can return pointers to arrays. Two options are: to allocate memory in function f or fill preallocated memory (preallocated by the caller). For example:
1.
name* f( int count) {
name *ret = malloc( count * sizeof( name));
if( !ret)
return NULL;
for( int i = 0; i < count; ++i)
// ret[i] = ... initialize
return ret;
};
int main() {
name *p = f(10);
if( p) {
// use p
free( p); // don't forget
}
return 0;
}
2.
void f( name* p, int count) {
if( !p)
return;
for( int i = 0; i < count; ++i)
// p[i] = ... initialize
};
int main() {
name *p = malloc( 10 * sizeof( name));
f( p, 10);
free( p); // don't forget
return 0;
}
3.
void f( struct name p[], int count) {
if( !p)
return;
for( int i = 0; i < count; ++i)
// p[i] = ... initialize
};
int main() {
name p[10];
f( p, 10);
return 0;
}
Upvotes: 2
Reputation:
Seems this has not been mentioned.
The reason why this approach is good as compared to creating dynamic memory inside function func
and returning pointer to it - is that in our case, caller owns the memory (which she created and passed to function - e.g., buff2
) and has to free it anyway. Whereas in the former case the caller might forget to free the memory returned by function. You can also use it in a way that there is no need to free anything at all (e.g., "first usage").
In C:
void func(struct name *x, int len)
{
for(int i = 0; i<len; i++)
{
// Init each array element x[i]
x[i].thing1="text1";
x[i].thing2="text2";
// etc.
}
}
You have to be careful to use correct len
value otherwise you will write past the array.
Usage:
int main()
{
// 1) One way - no dynamic memory
struct name buff1[10];
func(buff1,10);
// 2) Other way - with dynamic memory
struct name *buff2 = malloc(10*sizeof(struct name));
func(buff2,10);
free(buff2);
}
Upvotes: 2
Reputation: 14768
This is how I would do it.
typedef struct name
{
string thing1;
string thing2;
int thing3;
int thing4;
};
name** getNames(size_t count) {
size_t i;
name** names = malloc(count * sizeof(*names));
for(i = 0; i < count; i++) {
names[i] = malloc(sizeof(**names));
names[i]->thing1 = "foobar";
}
return names;
}
Edit: I just noticed this is about c++, so the other answer is probably better.
Upvotes: 4