Return variable struct members

大城市里の小女人 提交于 2020-02-04 09:58:28

问题


I need to return a struct with two values in it. A double value (time) and an uint8_t array with a variable size. I have two functions and both of them should return the same type of struct, but with different data members (data[9], data[64]).

I've already tried to create a struct with an additional member size, but this isn't working at all. size should initialize the array with a fixed length, but the compilers says that the variable size is not defined.

typedef struct Result {
    double time;
    int size;
    uint8_t data[size];
}

The previous wasn't working so I tried to create an empty array and initialize it within my functions, but did not work either.

typedef struct Result {
    double time;
    uint8_t data[];
} Result;

Result foo() {
    double time = 17.5;
    uint8_t data[9] = {0};
    Result res = {sizeof(data), time, data};
    return res;
}

Result bar() {
    double time = 9.5;
    uint8_t data[64] = {4};
    Result res = {sizeof(data), time, data};
    return res;
}

int main(void) {
    Result foo = foo();
    printf("%.6f\n", foo->time);
    uint8_t data[9] = foo->data;
    // work with data[9] ...

    Result bar = bar();
    printf("%.6f\n", bar->time);
    uint8_t data[64] = bar->data;
    // work with data[64] ...
}

I get this error message:

Error: return type is an incomplete type

The members of the struct should be available as shown in the main function. I think the compiler doesn't know how big the data array should be, but maybe someone can explain me this context and my question on how to return a struct with a variable sized array in it.

I would appreciate any help, thank you very much.


回答1:


You need to use a flexible array member (FAM):

typedef struct Result {
    double  time;
    size_t  size;
    uint8_t data[];
};

You can then allocate a block of memory with malloc() et al to hold the data:

uint8_t data[] = "This is the variable length payload";
struct Result *rp = malloc(sizeof(struct Result) + sizeof(data));
rp->size = sizeof(data);
strcpy(rp->data, data);
rp->time = 17.5;

return rp;

You can arrange for different amounts of data — adjust the size and use memmove() (or memcpy()) to copy it.




回答2:


An unsized array element as the last member of a struct is called a flexible array member. A struct with such a member can only be created via dynamic memory allocation, with enough space allocated for the desired size of the array.

You can do this as follows:

typedef struct Result {
    double time;
    int size;
    uint8_t data[];
} Result;

Result *foo(double time, int size) 
{
    Result *r = calloc(1, sizeof(Result) + size*sizeof(uint8_t));
    r->time = time;
    r->size = size;
    return r;
}


来源:https://stackoverflow.com/questions/55030392/return-variable-struct-members

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!