3

I want to save data in arrays called plist. These arrays can vary in size and are part of a structure called ParticleList. I know how to create one list of size n[0]. n[0] for example is of size 2. Thus, a list of size 2. But what do I have to do, if I want to create several lists with size n[0], n[1], n[2] of type ParticleList?

To cut a long story short: How should I modify my code in order to access lists of variable size somehow like pl[numberOfList].plist[PositionInArray] = -1 or `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);
}
7
  • 3
    I know how to create one list of size n[0]...what? Commented Jan 16, 2017 at 12:38
  • The sendPar function as it stands here is leaking memory. Other than that your question is quite unclear, you should elaborate a bit. Commented Jan 16, 2017 at 12:48
  • @SouravGhosh // Number of lists int nl = 3;// Size of lists int n[nl]; n[0] = 2; n[1] = 3; n[2]=4. Therefore I wanted to say, that I know how to create a list of size n[0] which equals 2. Thus a list of size 2. Commented Jan 16, 2017 at 12:52
  • @MichaelWalz I just want to use my struct ParticleList such that I have lists plist and the size of the list plistSize. And this for several list. Then I want to access the list somehow like pl[numberOfList].plist[PositionInArray] Commented Jan 16, 2017 at 12:57
  • call sendPar(&[n1], nl); to print the results for the list with size n[1], but the code still makes no sense... Commented Jan 16, 2017 at 12:57

2 Answers 2

3

Do you mean something like this?

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;          
}

This way you can access each item in each list by

pl[<index of list>].plist[<index of list item>]

A bit more dynamic by using flexible array members (this way one of the lists can be replaced by another list of different size):

Note that I changed the struct!

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;
}
Sign up to request clarification or add additional context in comments.

5 Comments

This example helps me! In my program list1 to list3 can change in size. So I have always three lists but the size may change during time. What would your code than look like?
@Samuel What exactly means that the size of the lists may change over the time? If the lists are growing or shrinking, but still holding the old values? Or is the complete list replaced by another list of different size?
After I used list1 to list3 in one time step I delete them to free the memory. Then in the next time step I determine the new lengths of the lists. So I have to allocate memory for three new lists.
Ok, then you have to use the flexible array member example from Lundin below... and create an array of ParticleList pointers. I'll create an example for you.
Great! Can you have a look at this: stackoverflow.com/questions/41678680/… Is this also a way to do it?
3

It would seem you are looking for the language feature called flexible array member. It works like this:

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

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

Where n is the size you want plist to have.

2 Comments

Can I use that and access the lists like pl[numberOfList].plist[positionInArray]?
@Samuel No because pl is not an array. If you want it to be an array, you must make it an array of pointers ParticleList *pl = malloc( sizeof(ParticleList*[something]) ); where each pointer points at a dynamically allocated item pl[i] = malloc( sizeof(ParticleList) + sizeof(double[n]) );. Then you can use that notation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.