Initializing Array of Structure in C

I have the following structure

typedef struct {
    int buf[BUF_SIZE]; // the buffer
    size_t len; // number of items in the buffer
    pthread_mutex_t mutex; // needed to add/remove data from the buffer
    pthread_cond_t can_produce; // signaled when items are removed
    pthread_cond_t can_consume; // signaled when items are added
};

Initially I was simply initializing it as follows

buffer_t buffer = {
    .len = 0,
    .mutex = PTHREAD_MUTEX_INITIALIZER,
    .can_produce = PTHREAD_COND_INITIALIZER,
    .can_consume = PTHREAD_COND_INITIALIZER
};

Although I would like to initialize an array of buffer_t with those values, although I'm not quite sure how to properly do it.

Something like

buffer_t buffer[NUM_ARRAY] = {
    .len = 0,
    .mutex = PTHREAD_MUTEX_INITIALIZER,
    .can_produce = PTHREAD_COND_INITIALIZER,
    .can_consume = PTHREAD_COND_INITIALIZER
};

(Which I realize is incorrect)

Edit: I ended up using

buffer_t buffers[NUM_THREADS];

for (i = 0, i < 3, i ++) {
       buffers[i] = (buffer_t) {
                .len = 0,
                .mutex = PTHREAD_MUTEX_INITIALIZER,
                .can_produce = PTHREAD_COND_INITIALIZER,
                .can_consume = PTHREAD_COND_INITIALIZER
            };  
}

Answers


If NUM_ARRAY isn't too big, you can do something like this:

#define NUM_ARRAY 3

buffer_t buffer[NUM_ARRAY] = {
    { {0}, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER},
    { {0}, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER},
    { {0}, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER}
};

Or you could explicitly code it like this:

buffer_t buffer[NUM_ARRAY];
int i;
for (i=0; i<NUM_ARRAY; i++) {
    memset(buffer[i].buf, 0, sizeof(buffer[i].buf));
    buffer[i].len = 0;
    buffer[i].mutex = PTHREAD_MUTEX_INITIALIZER;
    buffer[i].can_produce = PTHREAD_COND_INITIALIZER;
    buffer[i].can_consume = PTHREAD_COND_INITIALIZER;
}

EDIT:

So it looks like the PTHREAD_MUTEX_INITIALIZER and PTHREAD_COND_INITIALIZER macros can't be used in an assignment like this as it's meant to be used only in initializations and contains { and } characters.

So you need to use initialization syntax as others have suggested:

buffer_t buffer[NUM_ARRAY];
int i;
for (i=0; i<NUM_ARRAY; i++) {
    buffer[i] = (buffer_t) {
        0, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER
    };
}

You need to specify the curly braces to initialize the array, so your last example is incorrect indeed.

There are multiple ways to initialize the whole array with the same struct every time:

  1. Initialize each array member explicitly. Example:

    buffer_t buffer[NUM_ARRAY] = {
        {
            .len = 0,
            .mutex = PTHREAD_MUTEX_INITIALIZER,
            ...
        },
        {
            .len = 0,
            .mutex = PTHREAD_MUTEX_INITIALIZER,
        },
        ...
    };
    

    This is pretty tedious, though. A standardese way would be to...

  2. Use a for loop:

    buffer_t buffer[NUM_ARRAY];
    for (size_t i = 0; i < NUM_ARRAY; ++i) {
        buffer[i] = (buffer_t) {
            .len = 0,
            .mutex = PTHREAD_MUTEX_INITIALIZER,
            ...
        };
    }
    

    Way better1. However, there's still...

  3. Designated initializer lists. Some of them have been standardized like ones you are using but this one hasn't. Therefore it's a non-standard GCC extension but worth to mention anyway. Example:

    buffer_t buffer[NUM_ARRAY] = {
        [0 ... (NUM_ARRAY - 1)] = {
            .len = 0,
            .mutex = PTHREAD_MUTEX_INITIALIZER,
            ...
        }
    };
    

I recommend the 2nd option, though.


1 The (buffer_t) { } syntax is available only since C99. If your compiler doesn't support it, use simple assignment per struct member.


If your buffer is global, you can leave the initialization in this special case, because PTHREAD_MUTEX_INITIALIZER is a structure with all zeroes. Otherwise, you would have no other choice than to initialize all members or loop over it programmatically.


Generally you can initialise an array of structs something like this:

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

typedef struct buffer_t {
    int a;
    int b;
    int c;
} buffer_t;

int main()
{
    int i;
    int NUM_ARRAY=4;

    buffer_t buffer[NUM_ARRAY];

    for(i=0; i<NUM_ARRAY; i++)
    {
        buffer[i].a = 0;
        buffer[i].b = 1;
        buffer[i].c = 2;
    };

    return 0;
}

I feel like you're after more than this though?


Need Your Help

Android number format is wrong somehow, instead of 3.5 I get 3.499999999, why?

android numbers format rounding

I store some data in a database and I read those data with a cursor. All the data are 56.45 , 3.04, 0.03 type, so two numbers after the decimal point. Now I would like to sum them but it doesnt see...

SQL query that selects effective costing rate based on charge date

sql sql-server sql-server-2008

SQL novice here. I'm trying to generate a costing query that outputs employee time card information and calculates cost based on an effective employee costing rate.