Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.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_Struct - Fatal编程技术网

使用C在另一个结构中使用灵活长度的结构数组

使用C在另一个结构中使用灵活长度的结构数组,c,arrays,struct,C,Arrays,Struct,您好,我正在尝试使用C实现一个简单的结构: 2个盒子,每个盒子包含不同数量的颗粒;在main()中传递的粒子的确切数量 我编写了以下代码: typedef struct Particle{ float x; float y; float vx; float vy; }Particle; typedef struct Box{ Particle p[]; }Box; void make_box(Box *box, int number_of_partic

您好,我正在尝试使用C实现一个简单的结构:
2个盒子,每个盒子包含不同数量的颗粒;在main()中传递的粒子的确切数量

我编写了以下代码:

typedef struct Particle{
    float x;
    float y;
    float vx;
    float vy;
}Particle;

typedef struct Box{
    Particle p[];
}Box;

void make_box(Box *box, int number_of_particles);

int main(){
    Box b1, b2;
    make_box(&b1, 5);  //create a box containing 5 particles
    make_box(&b2, 10); //create a box containing 10 particles
}
我尝试用以下代码实现make_-box

void make_box(struct Box *box, int no_of_particles){
    Particle po[no_of_particles];
    po[0].x = 1;
    po[1].x = 2;
    //so on and so forth...
    box->p = po;
}

它总是给我“灵活数组成员的无效使用”。如果有人能对此有所了解,我们将不胜感激。

您不能指定给
粒子p[]
,只需使用
粒子*p

当然,您需要在堆上分配粒子阵列,而不是在堆栈上!否则,一旦您离开功能
make_box
,它将被销毁

void make_box(struct Box *box, int no_of_particles){
    Particle* po = (Particle*)malloc(sizeof(Particle)*no_of_particles);
    for (int i = 0; i < no_of_particles; i++)
        po[0].x = i;
    //so on and so forth...
    box->p = po;
}
struct Box *box1 = malloc(sizeof *box1 +
                          sizeof (Particle[number_of_particles]));

for (size_t i=0; i < number_of_particles; ++i)
    box1->p[i] = po[i];
/* or memcpy(box1->p, po, sizeof po); */

当不再需要内存时,不要忘记释放内存。

在Box struct中,为什么不使用指向粒子的指针来创建动态数组

void make_box(struct Box *box, int no_of_particles){
    Particle po[no_of_particles];
    //...
    box->p = po;
}
po
是一个局部变量,它的存储在堆栈上自动分配;返回它的地址是个坏主意。相反,您应该从堆中分配内存,并记住在处理完这些框后释放内存:

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

typedef struct Particle_ {
    float x;
    float y;
    float vx;
    float vy;
} Particle;

typedef struct Box_ {
    Particle *p;
} Box;

void make_box(Box *box, int no_of_particles);

void make_box(Box *box, int no_of_particles){
    Particle *po = (Particle *) malloc ( no_of_particles*sizeof(Particle) );
    po[0].x = 1;
    po[1].y = 2;
    //so on and so forth...
    box->p = po;
}

void destroy_box(Box *box){
    free(box->p);
}


int main(){
    Box b1, b2;
    make_box(&b1, 5);  //create a box containing 5 particles
    make_box(&b2, 10); //create a box containing 10 particles

    // do the job...
    printf("box b1, point 0, x: %5.2f\n", b1.p[0].x);
    printf("box b2, point 1, y: %5.2f\n", b2.p[1].y);

    destroy_box(&b1);
    destroy_box(&b2);

    return 0;
}
#包括
#包括
类型定义结构粒子{
浮动x;
浮动y;
浮动vx;
浮球;
}粒子;
类型定义结构框{
粒子*p;
}盒子;
void make_box(box*box,int no_的粒子);
void make_box(box*box,int no_的粒子){
Particle*po=(Particle*)malloc(无粒子数*sizeof(粒子));
po[0].x=1;
po[1],y=2;
//诸如此类。。。
方框->p=po;
}
空盒(盒*盒){
自由(方框->p);
}
int main(){
框b1、b2;
make_box(&b1,5);//创建一个包含5个粒子的框
make_-box(&b2,10);//创建一个包含10个粒子的框
//做这项工作。。。
printf(“b1框,点0,x:%5.2f\n”,b1.p[0].x);
printf(“框b2,点1,y:%5.2f\n”,b2.p[1].y);
销毁包装盒(b1和b1);
摧毁_盒(&b2);
返回0;
}

您需要动态分配
struct-Box

void make_box(struct Box *box, int no_of_particles){
    Particle* po = (Particle*)malloc(sizeof(Particle)*no_of_particles);
    for (int i = 0; i < no_of_particles; i++)
        po[0].x = i;
    //so on and so forth...
    box->p = po;
}
struct Box *box1 = malloc(sizeof *box1 +
                          sizeof (Particle[number_of_particles]));

for (size_t i=0; i < number_of_particles; ++i)
    box1->p[i] = po[i];
/* or memcpy(box1->p, po, sizeof po); */
struct Box*box1=malloc(sizeof*box1+
sizeof(粒子[粒子数]);
对于(尺寸i=0;i<粒子数;++i)
框1->p[i]=po[i];
/*或memcpy(框1->p,po,po尺寸)*/
但是,如果您正在执行上述操作,您还可以声明
struct-Box
中包含指针。如果希望
struct
中的所有数据都是连续的,那么灵活的数组成员“技巧”非常有用。如果在
struct
中有一个
点*
指针并动态分配它,那么
struct
和点的内存布局将不连续

出现错误的原因是无法在C中指定数组,而
box->p
是数组(来自N11246.7.2.1p16):

但是,当
(或
->
)运算符的左操作数是(指向)具有灵活数组成员的结构,而右操作数命名该成员时,其行为就好像该成员被替换为最长的数组(具有相同的元素类型)这不会使结构大于正在访问的对象;阵列的偏移量应保持柔性阵列构件的偏移量,即使这与替换阵列的偏移量不同。如果这个数组没有元素,它的行为就好像它有一个元素一样,但如果试图访问该元素或生成一个超过该元素的指针,则该行为是未定义的


除灵活数组成员外,您的
结构中还需要至少有一个其他成员。

如果您的结构具有灵活数组成员,则无法直接创建该类型的对象,因为编译器不知道您希望它的长度。这就是你试图用这一行来做的:

Box b1, b2;
这样的
struct
s总是需要动态分配,这意味着您只能声明指向它们的指针。因此,您将该声明更改为:

Box *b1, *b2;
…并更改
make_box()
函数以返回这样的指针:

Box *make_box(int no_of_particles)
{
    Box *box = malloc(sizeof *box + no_of_particles * sizeof box->p[0]);

    if (box)
    {
        box->p[0].x = 1;
        box->p[1].x = 2;
        //so on and so forth...
    }

    return box;
}

void destroy_box(Box *box){
    free(box);
}

int main()
{
    Box *b1 = make_box(5);  //create a box containing 5 particles
    Box *b2 = make_box(10); //create a box containing 10 particles

    // Test that b1 and b2 are not NULL, then do the job...

    destroy_box(b1);
    destroy_box(b2);

    return 0;
}
PS:
您还需要将至少一个其他成员添加到Box结构中(
no_of_particles
似乎是一个不错的选择),因为灵活数组成员不能是结构的唯一成员。

如果要使用“灵活数组”,它必须是结构中的最后一个元素。这只是因为编译器无法预测下一个元素的偏移量。此外,在分配结构时,需要为数组元素分配额外的内存

历史注释: 过去我经常看到的一件事是这样的练习

struct a {
  int x, y, z;
  char name[1];
};

struct a *  ptr;

ptr = (struct a*) malloc (sizeof (a) + EXTRA SPACE FOR name);

or

ptr = (struct a*) buffer;   /* <buffer> would have been a passed character array */
结构a{ int x,y,z; 字符名[1]; }; 结构a*ptr; ptr=(结构a*)malloc(sizeof(a)+名称的额外空格); 或 ptr=(结构a*)缓冲区;/*将是传递的字符数组*/
上述内容将允许用户访问超出[name]范围的内容。完全合法且有效的C,但有潜在危险,因为您将故意超出最初声明的[name]界限


小心点。

如果我没记错的话,C不允许使用数组大小的变量。C99允许。它被称为可变长度数组,或VLA。C99还通过引入“灵活的数组成员”来祝福“结构黑客”。谢谢,我一直是Java爱好者,对C来说是新手。内存分配的想法让我发疯。在main()中,我可以知道如何访问粒子阵列的每个元素吗?像Prtf(“%f”),b1.p(1)x)@费德里克,您可能想尝试BeeHEM GC,用于C或C++。您最近的观察是一个好的观点,但是MaxixBox()的第一条指令对我来说毫无意义。更好:Box=malloc(Box的大小);如果(长方体){box->nParticle=no_of_粒子;长方体->p=malloc(no_of_particlessizeof(粒子));如果(长方体->p{etc..,则无效销毁长方体(长方体*长方体){if(长方体){if(长方体){if