fsubcs
fsubcs

Reputation: 51

C++ Return Array of Structs

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

Answers (4)

Denis
Denis

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

4pie0
4pie0

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

user2793162
user2793162

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

SimpleJ
SimpleJ

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

Related Questions