【问题标题】:Struct with variable size of array具有可变数组大小的结构
【发布时间】:2017-01-16 12:37:04
【问题描述】:

我想将数据保存在名为plist 的数组中。这些数组的大小可以不同,并且是称为ParticleList 的结构的一部分。我知道如何创建一个大小为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);
}

【问题讨论】:

  • 我知道如何创建一个大小为n[0]的列表...什么?
  • 这里的sendPar 函数正在泄漏内存。除了你的问题不太清楚,你应该详细说明一下。
  • @SouravGhosh // Number of lists int nl = 3;// Size of lists int n[nl]; n[0] = 2; n[1] = 3; n[2]=4。因此我想说,我知道如何创建一个大小为 n[0] 的列表,它等于 2。因此,一个大小为 2 的列表。
  • @MichaelWalz 我只想使用我的结构ParticleList 这样我就有列表plist 和列表的大小plistSize。这有几个列表。然后我想以某种方式访问​​列表,例如pl[numberOfList].plist[PositionInArray]
  • 调用sendPar(&amp;[n1], nl);打印大小为n[1]的列表的结果,但代码仍然没有意义...

标签: c struct


【解决方案1】:

你的意思是这样的吗?

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[&lt;index of list&gt;].plist[&lt;index of list item&gt;]

通过使用 灵活的数组成员 更加动态(这样一个列表可以被另一个不同大小的列表替换):

注意我改变了结构!

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 可以改变大小。所以我总是有三个列表,但大小可能会随着时间的推移而改变。你的代码会是什么样子?
  • @Samuel 列表的大小可能会随着时间而改变究竟意味着什么?如果列表在增长或缩小,但仍保留旧值?还是完整列表被另一个不同大小的列表替换?
  • 在一个时间步骤中使用list1list3 后,我删除它们以释放内存。然后在下一个时间步骤中,我确定列表的新长度。所以我必须为三个新列表分配内存。
  • 好的,那么您必须使用下面 Lundin 中的 灵活数组成员 示例...并创建一个 ParticleList 指针数组。我将为您创建一个示例。
  • 太棒了!你可以看看这个:stackoverflow.com/questions/41678680/…这也是一种方法吗?
【解决方案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]这样的列表吗?
  • @Samuel 否,因为pl 不是数组。如果你希望它是一个数组,你必须使它成为一个指针数组ParticleList *pl = malloc( sizeof(ParticleList*[something]) );,其中每个指针指向一个动态分配的项目pl[i] = malloc( sizeof(ParticleList) + sizeof(double[n]) );。然后你就可以使用那个符号了。
猜你喜欢
  • 1970-01-01
  • 2011-11-07
  • 2011-06-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-13
  • 2010-09-15
  • 1970-01-01
相关资源
最近更新 更多