Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/jquery-ui/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C语言中柔性数组的柔性数组_C_Arrays_Flexible Array Member - Fatal编程技术网

C语言中柔性数组的柔性数组

C语言中柔性数组的柔性数组,c,arrays,flexible-array-member,C,Arrays,Flexible Array Member,是否可以在C中使用嵌套的灵活数组灵活数组灵活数组 我尝试了以下代码来测试灵活的阵列: #include <stdlib.h> #include <stdio.h> typedef struct { int x; int y; } node; typedef struct { int len; node elem[]; } cell; int cell_size = 3; int main(void) { cell *set

是否可以在C中使用嵌套的灵活数组灵活数组灵活数组

我尝试了以下代码来测试灵活的阵列:

#include <stdlib.h>
#include <stdio.h>

typedef struct {
    int x;
    int y;
} node;

typedef struct {
    int len;
    node elem[];
} cell;

int cell_size = 3;

int main(void) {
    cell *set = malloc(sizeof *set + cell_size * sizeof set->elem[0]);
    set->len = cell_size;

    for (int j = 0; j < cell_size; j++) {
        set->elem[j].x = j;
        set->elem[j].y = j * 10;
    }

    printf("set size: %d\n", set->len);
    for (int j = 0; j < cell_size; j++) {
        printf("x: %d, ", set->elem[j].x);
        printf("y: %d\n", set->elem[j].y);
    }

    return 0;
}
这里一切都很好。为集合分配的空间为28字节

但当我试图修改此代码以将flexible数组放入其他数组中时:

#include <stdlib.h>
#include <stdio.h>


typedef struct {
    int x;
    int y;
} node;


typedef struct {
    int len;
    node elem[];
} cell;


typedef struct {
    int len;
    cell group[];
} obj;


int cell_size = 3;
int obj_size = 4;

int main(void) {

    obj *set = malloc(
        sizeof *set + obj_size * sizeof (
        sizeof (cell) + cell_size * sizeof(node)
    ));
    set->len = obj_size;

    for (int i = 0; i < obj_size; i++) {
        set->group[i].len = cell_size;
        for (int j = 0; j < cell_size; j++) {
            set->group[i].elem[j].x = j;
            set->group[i].elem[j].y = j * 10 + i;
        }
    }

    printf("set size: %d\n", set->len);
    for (int i = 0; i < obj_size; i++) {
        printf("group size: %d\n", set->group[i].len);
        for (int j = 0; j < cell_size; j++) {
            printf("x: %d, ", set->group[i].elem[j].x);
            printf("y: %d\n", set->group[i].elem[j].y);
        }
    }

    return 0;
}
即使我手动将malloc设置为任何合理的值,输出仍然不正确。我认为这是因为编译器不知道顶级结构obj中group[]成员的大小。但是,我没有收到任何编译器错误或警告GCC6.3.0


我不知道如何设置这个大小并使编译器正确处理代码。

正确。。。没有办法制作嵌套的灵活数组

数组的所有成员必须具有相同的大小。你一定有

sizeof arr[i] == sizeof arr[j]

对于数组边界内的所有i,j。

正确。。。没有办法制作嵌套的灵活数组

数组的所有成员必须具有相同的大小。你一定有

sizeof arr[i] == sizeof arr[j]

对于数组边界内的所有i,j。

具有灵活数组成员的结构不能用作其他结构或数组中的成员。你只能有一个家庭。否则,如果您试图声明一个FAM数组,struct数组的每个FAM成员都会指向相邻数组成员之间的内存位置,这会导致您看到不正确的覆盖结果

有关C标准适用章节的完整讨论,请参见:

那么,有没有办法让嵌套的灵活数组工作

回答:没有

那将违反

类似的东西

回答:是的

所有您需要做的就是使node元素[];节点*元素;然后为每个集合分配单元大小*节点字节大小->组[i]。元素,例如

示例使用/输出

内存使用/错误检查


请仔细查看,如果您还有其他问题,请告诉我。

具有灵活数组成员的结构不能用作其他结构或数组中的成员。你只能有一个家庭。否则,如果您试图声明一个FAM数组,struct数组的每个FAM成员都会指向相邻数组成员之间的内存位置,这会导致您看到不正确的覆盖结果

有关C标准适用章节的完整讨论,请参见:

那么,有没有办法让嵌套的灵活数组工作

回答:没有

那将违反

类似的东西

回答:是的

所有您需要做的就是使node元素[];节点*元素;然后为每个集合分配单元大小*节点字节大小->组[i]。元素,例如

示例使用/输出

内存使用/错误检查


仔细检查一下,如果您还有其他问题,请告诉我。

您不能拥有编译时未知大小的灵活对象数组。并且具有灵活数组成员的结构的大小不是。唯一已知的是它的尺寸,没有柔性构件

但在您的用例中,所有灵活的阵列都将具有相同的大小,即使它只在运行时已知。因此,您可以用指针替换内部结构的灵活数组,为结构分配足够的空间,包括其灵活数组加上所有节点的足够空间,并在该自由空间中分配指针。代码可以是:

#include <stdlib.h>
#include <stdio.h>


typedef struct {
    int x;
    int y;
} node;


typedef struct {
    int len;
    node *elem;
} cell;


typedef struct {
    int len;
    cell group[];
} obj;


int cell_size = 3;
int obj_size = 4;

int main(void) {

    obj *set = malloc(
        sizeof *set + obj_size * (
            sizeof(cell) + cell_size * sizeof(node)
            ));
    set->len = obj_size;

    // nodes will exist in the allocated buffer after the cells
    node *node_start = (node *)(((char *) set) + sizeof *set + obj_size * sizeof(cell));

    for (int i = 0; i < obj_size; i++) {
        set->group[i].len = cell_size;
        // assign the elem pointers in the free space
        set->group[i].elem = node_start + i * cell_size;
        for (int j = 0; j < cell_size; j++) {
            set->group[i].elem[j].x = j;
            set->group[i].elem[j].y = j * 10 + i;
        }
    }

    printf("set size: %d\n", set->len);
    for (int i = 0; i < obj_size; i++) {
        printf("group size: %d\n", set->group[i].len);
        for (int j = 0; j < cell_size; j++) {
            printf("x: %d, ", set->group[i].elem[j].x);
            printf("y: %d\n", set->group[i].elem[j].y);
        }
    }
    free(set);
    return 0;
}

不能有编译时大小未知的灵活对象数组。并且具有灵活数组成员的结构的大小不是。唯一已知的是它的尺寸,没有柔性构件

但在您的用例中,所有灵活的阵列都将具有相同的大小,即使它只在运行时已知。因此,您可以用指针替换内部结构的灵活数组,为结构分配足够的空间,包括其灵活数组加上所有节点的足够空间,并在该自由空间中分配指针。代码可以是:

#include <stdlib.h>
#include <stdio.h>


typedef struct {
    int x;
    int y;
} node;


typedef struct {
    int len;
    node *elem;
} cell;


typedef struct {
    int len;
    cell group[];
} obj;


int cell_size = 3;
int obj_size = 4;

int main(void) {

    obj *set = malloc(
        sizeof *set + obj_size * (
            sizeof(cell) + cell_size * sizeof(node)
            ));
    set->len = obj_size;

    // nodes will exist in the allocated buffer after the cells
    node *node_start = (node *)(((char *) set) + sizeof *set + obj_size * sizeof(cell));

    for (int i = 0; i < obj_size; i++) {
        set->group[i].len = cell_size;
        // assign the elem pointers in the free space
        set->group[i].elem = node_start + i * cell_size;
        for (int j = 0; j < cell_size; j++) {
            set->group[i].elem[j].x = j;
            set->group[i].elem[j].y = j * 10 + i;
        }
    }

    printf("set size: %d\n", set->len);
    for (int i = 0; i < obj_size; i++) {
        printf("group size: %d\n", set->group[i].len);
        for (int j = 0; j < cell_size; j++) {
            printf("x: %d, ", set->group[i].elem[j].x);
            printf("y: %d\n", set->group[i].elem[j].y);
        }
    }
    free(set);
    return 0;
}

这看起来很可疑:sizeof sizeof cell+cell_size*sizeofnode结构的大小中不包含FAM。因此,在为组数组编制索引时,它不会在嵌套单元格中包含元素数组的大小。@ChristianGibbons是的,可能是此计算不正确,但问题不是分配,而是代码的错误行为。即使我设置了malloc10000,输出仍然是不正确的。@Barmar那么,没有办法让嵌套的灵活数组工作吗?类似的东西?添加-迂腐的警告警告:使用灵活数组成员的结构无效-单元格组[];这看起来很可疑:sizeof sizeof cell+cell_size*sizeofnode结构的大小中不包含FAM。因此,在为组数组编制索引时,它不会在嵌套单元格中包含元素数组的大小。@ChristianGibbons是的,可能是此计算不正确,但问题不是分配,而是代码的错误行为。即使我设置了malloc10000,输出仍然是不正确的。@Barmar那么,没有办法让嵌套的灵活数组工作吗?西米拉
r?添加-迂腐警告警告:使用灵活数组成员的结构无效-单元格组[];灵活的数组成员既不是静态的,也不是静态的。每个灵活数组成员必须是结构的最后一个成员,并且至少有一个其他成员,但没有理由不能在转换单元中包含多个灵活数组成员。这就是你所说的“编译单元”吗?而且,如果有人试图构建一个包含灵活数组成员的结构数组,那么他们没有理由都“指向”同一个地址。如果有什么区别的话,柔性数组成员将在下一个结构的开头加上或减去一些填充,而不是它的最后一个成员。如果有结构foo{int a;int fam[];},则不能声明foo数组,因为fam将具有相同的地址。虽然技术上不是静态的,但行为是相同的。我将查找详细讨论此问题的SO链接@EricPostphil好吧,我想我已经注意到了术语,以及使用FAM声明stuct数组将导致阵列FAM成员指向的效果。不是相同的位置,相对于每个数组元素的相同位置在包含FAM.@DavidC.Rankin的相邻数组元素之间结束。谢谢,代码工作正常。我很感激你的回答。灵活的数组成员既不是静态的也不是静态的。每个灵活数组成员必须是结构的最后一个成员,并且至少有一个其他成员,但没有理由不能在转换单元中包含多个灵活数组成员。这就是你所说的“编译单元”吗?而且,如果有人试图构建一个包含灵活数组成员的结构数组,那么他们没有理由都“指向”同一个地址。如果有什么区别的话,柔性数组成员将在下一个结构的开头加上或减去一些填充,而不是它的最后一个成员。如果有结构foo{int a;int fam[];},则不能声明foo数组,因为fam将具有相同的地址。虽然技术上不是静态的,但行为是相同的。我将查找详细讨论此问题的SO链接@EricPostphil好吧,我想我已经注意到了术语,以及使用FAM声明stuct数组将导致阵列FAM成员指向的效果。不是相同的位置,相对于每个数组元素的相同位置在包含FAM.@DavidC.Rankin的相邻数组元素之间结束。谢谢,代码工作正常。谢谢你的回答。
#include <stdlib.h>
#include <stdio.h>

typedef struct {
    int x;
    int y;
} node;

typedef struct {
    int len;
    node *elem;
} cell;


typedef struct {
    int len;
    cell group[];
} obj;


int cell_size = 3;
int obj_size = 4;

int main (void) {

    obj *set = malloc (sizeof *set + obj_size * sizeof (cell));
    set->len = obj_size;

    for (int i = 0; i < obj_size; i++) {
        set->group[i].len = cell_size;
        set->group[i].elem = malloc (cell_size * sizeof (node));
        for (int j = 0; j < cell_size; j++) {
            set->group[i].elem[j].x = j;
            set->group[i].elem[j].y = j * 10 + i;
        }
    }

    printf("set size: %d\n", set->len);
    for (int i = 0; i < obj_size; i++) {
        printf("group size: %d\n", set->group[i].len);
        for (int j = 0; j < cell_size; j++) {
            printf("x: %d, ", set->group[i].elem[j].x);
            printf("y: %d\n", set->group[i].elem[j].y);
        }
        free (set->group[i].elem);
    }

    free (set);

    return 0;
}
$ ./bin/fam_array2
set size: 4
group size: 3
x: 0, y: 0
x: 1, y: 10
x: 2, y: 20
group size: 3
x: 0, y: 1
x: 1, y: 11
x: 2, y: 21
group size: 3
x: 0, y: 2
x: 1, y: 12
x: 2, y: 22
group size: 3
x: 0, y: 3
x: 1, y: 13
x: 2, y: 23
$ valgrind ./bin/fam_array2
==7686== Memcheck, a memory error detector
==7686== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==7686== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==7686== Command: ./bin/fam_array2
==7686==
set size: 4
group size: 3
x: 0, y: 0
x: 1, y: 10
x: 2, y: 20
group size: 3
x: 0, y: 1
x: 1, y: 11
x: 2, y: 21
group size: 3
x: 0, y: 2
x: 1, y: 12
x: 2, y: 22
group size: 3
x: 0, y: 3
x: 1, y: 13
x: 2, y: 23
==7686==
==7686== HEAP SUMMARY:
==7686==     in use at exit: 0 bytes in 0 blocks
==7686==   total heap usage: 5 allocs, 5 frees, 168 bytes allocated
==7686==
==7686== All heap blocks were freed -- no leaks are possible
==7686==
==7686== For counts of detected and suppressed errors, rerun with: -v
==7686== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
#include <stdlib.h>
#include <stdio.h>


typedef struct {
    int x;
    int y;
} node;


typedef struct {
    int len;
    node *elem;
} cell;


typedef struct {
    int len;
    cell group[];
} obj;


int cell_size = 3;
int obj_size = 4;

int main(void) {

    obj *set = malloc(
        sizeof *set + obj_size * (
            sizeof(cell) + cell_size * sizeof(node)
            ));
    set->len = obj_size;

    // nodes will exist in the allocated buffer after the cells
    node *node_start = (node *)(((char *) set) + sizeof *set + obj_size * sizeof(cell));

    for (int i = 0; i < obj_size; i++) {
        set->group[i].len = cell_size;
        // assign the elem pointers in the free space
        set->group[i].elem = node_start + i * cell_size;
        for (int j = 0; j < cell_size; j++) {
            set->group[i].elem[j].x = j;
            set->group[i].elem[j].y = j * 10 + i;
        }
    }

    printf("set size: %d\n", set->len);
    for (int i = 0; i < obj_size; i++) {
        printf("group size: %d\n", set->group[i].len);
        for (int j = 0; j < cell_size; j++) {
            printf("x: %d, ", set->group[i].elem[j].x);
            printf("y: %d\n", set->group[i].elem[j].y);
        }
    }
    free(set);
    return 0;
}