具有柔性阵列构件的返回结构

时间:2013-07-18 13:15:43

标签: c return-value

我需要从C函数返回一个具有灵活数组成员的结构,但是无法弄清楚它为什么不能编译。我知道返回数组可以通过将它们封装在结构中来实现,如下所示:

struct data_array {
    long length;
    double data[];
};

我的功能如下:

struct data_array test (int length) {
    struct data_array a;
    double* b = malloc (1000);
    a.length = 1000;
    a.data = b;
    return a;
}

但是,编译器返回:“无效使用灵活的数组成员”。

根据“21世纪C”一书,结构中的数据数组被作为指针处理(这对我来说非常有意义)。它尚未初始化,因此不应分配任何内存来保存其数据。 (甚至编译器也不知道需要多少内存)。所以我必须分配内存并将其分配给我的返回变量。

那么,为什么编译器会返回错误?我该如何解决这个问题?

7 个答案:

答案 0 :(得分:4)

您可以将data声明为不完整的数组(没有指定维度的数组)或将其声明为指针。 (结构中的不完整数组必须是最后一个成员,并且称为灵活数组成员。)

如果您声明它是一个不完整的数组,那么该结构基本上包含length元素和为其分配的数组元素。您必须为结构的基本大小和所有元素的空间分配它,如:

struct data_array *b = malloc(sizeof *b + NumberOfElements * sizeof *b->data);

但是,您无法返回以这种方式分配的结构,因为函数的返回类型必须是完整类型。不允许使用具有灵活阵列成员的结构。但是,您可以返回指向结构的指针。因此,您可以返回b,但不能返回*b

如果您声明data是指针,那么您创建结构并单独为data分配空间以指向,如:

struct data_array b;
b.length = NumberOfElements;
b.data = malloc(NumberOfElements * sizeof *b.data);

以下是代码示例。首先,使用灵活的数组成员:

struct data_array
{
    long length;
    double data[];
};

struct data_array *test(size_t NumberOfElements)
{
     struct data_array *b = malloc(sizeof *b + NumberOfElements * sizeof *b->data);
     // Put code here to test the result of malloc.
     b->length = NumberOfElements;
     return b;
}

或者用指针:

struct data_array
{
    long length;
    double *data;
};

struct data_array test(size_t NumberOfElements)
{
     struct data_array b = { NumberOfElements,
         malloc(sizeof *b + NumberOfElements * sizeof *b->data) };
     // Put code here to test the result of malloc.
     return b;
}

答案 1 :(得分:0)

您正尝试在

行更改数组的基址
a.data = b;

无法修改数组基址,数组基址是常量指针。

答案 2 :(得分:0)

至于您无法将double*转换为double[]的原因,您可以参考this question that was asked before

至于解决问题,将double data[];更改为double *data;将有效。

新增更新

double* b = malloc(sizeof(double) * 1000);

答案 3 :(得分:0)

少数事情:

1)将struct defenation更改为:

 struct data_array {
    long length;
    double* data;
          ^
};

2)这是你应该如何使用malloc为你的数组分配内存:

a.data =  malloc (length * sizeof(double));

修改

错误太多,请遵循以下代码:

#include <stdio.h>
#include <stdlib.h>
struct data_array {
    long length;
    double* data;
};
struct data_array* test (int length) {
    struct data_array* a;
    a = malloc (sizeof (data_array));
    a->data = malloc (length*sizeof(double));
    a->length = length;
    return a;
}

int main () {
    data_array* x;
    x = test (5);
    for (int i=0; i<5; i++) {
        x->data[i] = i+0.5;
    }
    for (int i=0; i<5; i++) {
        printf ("%f\n" , x->data[i]);
    }
}

注意你可能需要在使用maloc时向类型添加强制转换(我的视觉强制我这样做,否则它是编译错误。但它只是故障)。

答案 4 :(得分:0)

struct data_array * test(long length) {
    struct data_array *a = calloc(1,sizeof(struct data_array) + length*sizeof(double));
    a->length = length;
    return a;
}

答案 5 :(得分:0)

我使用gcc,我想可能就是这样:

struct data_array {
    long length;
    double* data;
};
struct data_array* test (int length) {
    struct data_array* a =(struct data_array *) malloc (sizeof (data_array));
    a->data = malloc (length*sizeof(double));
    a->length = length;
    return a;
}

答案 6 :(得分:-1)

像你这样的灵活数组成员(结构定义中没有给出data的大小)的结构将被分配如下:

struct data_array *a;   // pointer!!
a = malloc( sizeof(struct data_array) + 1000 * sizeof(double) );

sizeof(struct data_array)是除data之外的结构的常量大小,1000是所需的数组大小。 当然,将data更改为指针并单独分配它也会起作用,但这有点不同。