Возвращаем переменные члены структуры - PullRequest
2 голосов
/ 06 марта 2019

Мне нужно вернуть структуру с двумя значениями.Двойное значение (time) и массив uint8_t с переменным размером.У меня есть две функции, и они оба должны возвращать один и тот же тип структуры, но с разными членами данных (data[9], data[64]).

Я уже пытался создать структуру с дополнительным членом size,но это не работает вообще.size должен инициализировать массив с фиксированной длиной, но компиляторы говорят, что размер переменной не определен.

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

Предыдущий не работал, поэтому я попытался создать пустой массив и инициализировать егов моих функциях, но также не работал.

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] ...
}

Я получаю это сообщение об ошибке:

Error: return type is an incomplete type

Члены структуры должны быть доступны, как показано в основной функции.Я думаю, что компилятор не знает, насколько большим должен быть массив data, но, возможно, кто-то может объяснить мне этот контекст и мой вопрос о том, как вернуть структуру с массивом переменного размера.

IБуду признателен за любую помощь, большое спасибо.

Ответы [ 2 ]

2 голосов
/ 06 марта 2019

Элемент массива без размера в качестве последнего члена структуры называется гибкий элемент массива .Структура с таким членом может быть создана только посредством динамического выделения памяти, с достаточным пространством, выделенным для желаемого размера массива.

Вы можете сделать это следующим образом:

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;
}
2 голосов
/ 06 марта 2019

Вам необходимо использовать член гибкого массива (FAM):

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

Затем вы можете выделить блок памяти с помощью malloc() и др. Для хранения данных:

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;

Вы можете упорядочить различные объемы данных - отрегулируйте размер и используйте memmove() (или memcpy()) для его копирования.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...