Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does C have a shorthand way of initialize a struct with malloc and set its fields?

I have a messy block of code like

result = (node*)malloc(sizeof(node));
result->fx = (char*)malloc(sizeof(char) * 2);
result->fx[0]='x'; result->fx[1]='\0';
result->gx = NULL; result->op = NULL; result->hx = NULL;

where I initialize an element of type

typedef struct node
{
    char * fx; // function
    struct node * gx; // left-hand side
    char * op; // operator
    struct node * hx; // right-hand side
} node;

Is there a shorthand way of doing that? In other words, is there a way to do like I would do in C++?

result = new node { new char [] {'x','\0'}, NULL, NULL, NULL };
like image 263
Microsoft Orange Badge Avatar asked May 26 '15 05:05

Microsoft Orange Badge


2 Answers

You can write your own wrapper function:

static node *getNewNode(char *fx) {
  node *p = calloc(1, sizeof *p);
  if(p && fx) {
    p->fx = malloc(strlen(fx) + 1);
    if(!p->fx) {
      free(p);
      p = null;
    } else {
      strcpy(p->fx, fx);
    }
  }
  return p;
}

Later you can call this as:

node *result = getNewNode("x");
if(result) ...

Which is more readable and less cluttery.

like image 191
Mohit Jain Avatar answered Oct 17 '22 16:10

Mohit Jain


You can't have two nested mallocs and initialize everything in one go. However I would suggest the following design:

typedef struct node
{
    char fx[2], op[2];    // first byte being null indicates not-present
    struct node *gx, *hx;
} node;

and then you can more simply write:

node *result = malloc( sizeof *result );

if ( !result )
    errorhandling......

// C89
node temp = { "x" };
*result = temp;

// C99
*result = (node){ .fx = "x" };

The C99 example uses compound literals and designated initializers which are in C but not C++. For more discussion see How to initialize a struct in ANSI C.

You don't have to use the designated initializer but it reduces the possibility for error. Any struct members not explicitly initialized will be initialized as if by 0.

In both cases, the theoretical temporary object will be optimized away, so this solution should not be considered inefficient at all.

like image 37
M.M Avatar answered Oct 17 '22 17:10

M.M