Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The most efficient way to initialize array member of struct?

Tags:

c

I have declared the struct

struct wnode {
  char *word;
  int lines[MAXLINES];
  struct wnode *left;
  struct wnode *right;
};

and the pointer

struct wnode *p;

The pointer is passed to a function. In that function, I first allocate memory for the pointer with malloc. Then I want to initialize the struct member lines to zero zero out the struct member lines.

An array initialization method will not work as it is interpreted as assignment:

p->lines[MAXLINES] = {0};

The compiler throws the error:

error: expected expression before '{' token

In the end, I'm just using a for loop to zero out the lines array:

for (i = 0; i < MAXLINES; i++)
  p->lines[i] = 0;

Is there a better way?

like image 876
Yannis Avatar asked Jul 07 '20 19:07

Yannis


4 Answers

The only time an array variable can be initialized in this manner:

int someInt[MAXLINES] = {0};

Is during declaration.

But because this particular variable int lines[MAXLINES]; is declared within the confines of struct, which does not allow members to be initialized, the opportunity is lost to that method, requiring it to be initialized after the fact, and using a different method.

The most common (and preferred) way to initialize after declaration in this case is to use:

//preferred
memset(p->lines, 0, sizeof(p->lines));

A more arduous method, and one that is seen often, sets each element to the desired value in a loop:

for(int i=0;i<MAXLINES;i++)
{
    p->lines[i] = 0;
}

As noted in comments, this method will be reduced by a good optimizing compiler to the equivalent of an memset() statement anyway.

like image 190
ryyker Avatar answered Oct 01 '22 00:10

ryyker


Arrays cannot be assigned to directly. You need to either use a loop to set all fields to 0 or you can use memset:

memset(p->lines, 0, sizeof(p->lines));

Note that for non-char types you can only to do this to set all members to 0. For any other value you need a loop.

like image 38
dbush Avatar answered Oct 22 '22 10:10

dbush


If you want to use the = operator, you can do it this way:

struct wnode wn, *p;
/* ........ */
wn = (struct wnode){.word = wn.word, .lines = {0,}, .left = wn.left, .right = wn.right};
*p = (struct wnode){.word = p ->word, .lines = {0,}, .left = p -> left, .right = p -> right};
like image 5
0___________ Avatar answered Oct 22 '22 12:10

0___________


= {0} works only on initialization. You can't use it with assignment as such which is why you get the error.

You can either use a for loop as you said or use memset to zero out the array:

memset(p -> lines, 0, sizeof(p -> lines))
like image 4
Spikatrix Avatar answered Oct 22 '22 10:10

Spikatrix