可变数组大小的结构体

3
我想要在被称为ParticleList的结构中保存名为plist的数组数据。这些数组的大小可能会有所不同。我知道如何创建一个大小为n[0]的列表。例如,n[0]的大小为2。因此,这是一个大小为2的列表。但是,如果我想要创建几个大小为n[0]、n[1]、n[2]ParticleList类型的列表,我该怎么做呢?
简而言之:我应该如何修改我的代码以便访问可变大小的列表,类似于pl[numberOfList].plist[PositionInArray]=-1或者`pl[numberOfList]->plist[PositionInArray]=-1'?
#include <stdlib.h>
#include <stdio.h>

typedef struct{
    double *plist;
    int plistSize;
} ParticleList;

void sendPar(int *n, int nl){

    // Allocate memory for struct ParticleList
    ParticleList *pl = malloc(sizeof(ParticleList));

    // Allocate memory for list
    pl->plist = malloc(sizeof(double)*n[0]);

    // Fill list with data
    for(int k=0; k<n[0]; k++){
        pl->plist[k] = -1;
    }
    // Write size of list into file
    pl->plistSize = n[0];

    // Print data
    printf("Content of list:\n");
    for(int k=0; k<n[0]; k++){
        printf("%lf\n", pl->plist[k]);
    }
    printf("Size of list: %d\n", pl->plistSize);


    // Free memory
    free(pl);
}

int main(){
    // Number of lists
    int nl = 3;

    // Size of lists
    int n[nl];
    n[0] = 2;
    n[1] = 3;
    n[2] = 4;

    sendPar(n, nl);
}

2
我知道如何创建一个大小为n[0]的列表...什么? - undefined
@SouravGhosh // 列表的数量 int nl = 3;// 列表的大小 int n[nl]; n[0] = 2; n[1] = 3; n[2]=4。因此,我想说,我知道如何创建一个大小为n[0]的列表,即2个元素的列表。 - undefined
调用sendPar(&[n1], nl);来打印大小为n[1]的列表的结果,但是这段代码仍然没有意义... - undefined
@gmug 这段代码只是一个简化版本。我只想能够访问变量大小的列表,例如 pl[numberOfList].plist[PositionInArray] = -1,但不知道如何实现。 - undefined
你的struct没有一个变量数组。指针不是一个数组,而且结构体有固定的大小。如果要使用可变长度数组的struct,请参考“灵活数组成员”(FAM)。 - undefined
显示剩余2条评论
2个回答

3
你的意思是这样的吗?
typedef struct{
    int plistSize;
    double* plist;
} ParticleList;

int main()
{
    int i, z = 0;

    /* Assuming you have three lists with three different sizes */
    double list1[2] = {-1.0, -1.1};
    double list2[3] = {-2.0, -2.1, -2.2};
    double list3[4] = {-3.0, -3.1, -3.2, -3.3};

    /* Create an array of three Particle Lists */
    ParticleList pl[3] = {{list1, 2},{list2, 3},{list3, 4}};

    /* Access the values in the Particle Lists */
    for(i = 0; i < 3; i++)
    {
        printf("ParticleList pl[%i]:\n", i);

        for(z = 0; z < pl[i].plistSize; z++)
        {
            printf("pl[%i].plist[%i] = %f\n", i, z, pl[i].plist[z]);
        } 
    }

    /* Change the first item of the second list */
    pl[1].plist[0] = 2.3;          
}

这样你就可以通过pl[<list索引>].plist[<列表项索引>]访问每个列表中的每个项目。
使用灵活数组成员使其更加动态(这样可以用不同大小的另一个列表替换其中一个列表): 注意,我已经改变了结构!
typedef struct{
    int plistSize;
    double plist[];
} ParticleList;

int main()
{
    int i, z = 0;
    ParticleList *pl[3];

    /* Allocate memory for the lists */
    pl[0] = malloc( sizeof(ParticleList) + sizeof(double[2]) );
    pl[0]->plistSize = 2;
    pl[1] = malloc( sizeof(ParticleList) + sizeof(double[3]) );
    pl[1]->plistSize = 3;
    pl[2] = malloc( sizeof(ParticleList) + sizeof(double[4]) );
    pl[2]->plistSize = 4;

    /* Write the values in the Particle Lists */
    for(i = 0; i < 3; i++)
    {
        printf("ParticleList pl[%i]:\n", i);

        for(z = 0; z < pl[i]->plistSize; z++)
        {
            pl[i]->plist[z] = -i;
        } 
    }

    /* Print the values */
    for(i = 0; i < 3; i++)
    {
        printf("ParticleList pl[%i]:\n", i);

        for(z = 0; z < pl[i]->plistSize; z++)
        {
            printf("pl[%i]->plist[%i] = %f\n", i, z, pl[i]->plist[z]);
        } 
    }

    /* Change the first value of the second list */
    pl[1]->plist[0] = -1.1;

    /* Replace the first list by a new one */
    free(pl[0]);
    pl[0] = malloc( sizeof(ParticleList) + sizeof(double[5]) );
    pl[0]->plistSize = 5;  

    /* Assign some new values to the new list 1 */
    pl[0]->plist[0] = -4.1;
    pl[0]->plist[1] = -4.2;
    pl[0]->plist[2] = -4.3;
    pl[0]->plist[3] = -4.4;
    pl[0]->plist[4] = -4.5;

    /* Print the values */
    for(i = 0; i < 3; i++)
    {
        printf("ParticleList pl[%i]:\n", i);

        for(z = 0; z < pl[i]->plistSize; z++)
        {
            printf("pl[%i]->plist[%i] = %f\n", i, z, pl[i]->plist[z]);
        } 
    } 

    /* free all lists before exiting the program */
    for(i = 0; i < 3; i++)
    {
        free(pl[i]);
    }

    return 0;
}

这个例子对我很有帮助!在我的程序中,list1list3的大小是可变的。所以我总是有三个列表,但是它们的大小可能会随时间而变化。那么你的代码会是什么样呢? - undefined
@Samuel 什么意思是列表的大小可能随时间变化?如果列表在增长或缩小,但仍保留旧值呢?还是完整的列表被另一个不同大小的列表替换了? - undefined
在一个时间步骤中,我使用了list1list3,然后删除它们以释放内存。接下来,在下一个时间步骤中,我确定了这些列表的新长度。因此,我需要为三个新列表分配内存。 - undefined
好的,那么你需要使用Lundin提供的灵活数组成员示例...并创建一个ParticleList指针数组。我会为你创建一个示例。 - undefined
太好了!你能看一下这个吗:http://stackoverflow.com/questions/41678680/deallocate-memory-with-free-does-not-work 这也是一种方法吗? - undefined

2

看起来您正在寻找称为灵活数组成员的语言功能。它的工作方式如下:

typedef struct{
    int plistSize;
    double plist[];
} ParticleList;

ParticleList *pl = malloc( sizeof(ParticleList) + sizeof(double[n]) );
pl->plistSize = n;
...
free(pl);

这里的 n 是您希望 plist 具有的大小。


我可以使用那个并且像 pl[numberOfList].plist[positionInArray] 这样访问列表吗? - undefined
@Samuel 不行,因为pl不是一个数组。如果你想让它成为一个数组,你必须将其定义为指针数组 ParticleList *pl = malloc( sizeof(ParticleList*[something]) );,其中每个指针指向一个动态分配的项目 pl[i] = malloc( sizeof(ParticleList) + sizeof(double[n]) );。然后你可以使用这种表示法。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接