carl.hiass
carl.hiass

Reputation: 1774

Initializing a struct with malloc

To create a struct I can do one of the following:

// Method 1
Item *item = malloc(sizeof(Item));
Item _item = {.name="job"};
item = &_item;

// Method 2
Item *item = malloc(sizeof(Item));
item->name="job";

Is there a simpler method to do this? Perhaps something along the lines of:

malloc(sizeof(Item)) & (Item) {.name="job"}

Here are the two methods: https://godbolt.org/z/MfYGW3

Upvotes: 0

Views: 98

Answers (3)

John Bode
John Bode

Reputation: 123468

There is no good way to dynamically allocate a struct instance and initialize its members in the same statement. You can write your own function to abstract out that operation:

struct Item *newItem( const char *name /*,  any additional arguments */ )
{
  struct Item *item = malloc( sizeof *item );
  if ( item )
  {
    item->name = malloc( strlen( name ) + 1 );
    if ( item->name )
    {
      strcpy( item->name, name );
    }
  }
  /**
   * allocate/assign any additional members here
   */
  return item;
}

int main( void )
{
  struct Item *myItem = newItem( "job" /*, any additional arguments */ );
  ...
}

That's about as good as it gets.

EDIT

Or you could assign a compound literal to the allocated instance as the other answers show. This method has the benefit of being a "deep" copy - any members that are themselves pointers to allocated memory will wind up pointing to new instances, not the same instance as the original.

Upvotes: 3

entangled_photon
entangled_photon

Reputation: 457

Are you looking for something like this?

#include <stdlib.h>

typedef struct {
    const char* name;
} Item;

int main() {
    Item* item = malloc(sizeof(Item));
    *item = (Item){.name = "Hello"};
    // do work    
    free(item);
    return 0;
}

Compiles with GCC 10.2.0 -Wall -Wextra with no errors or warnings.

Upvotes: 3

koder
koder

Reputation: 2093

Use a compound literal:

Item *item = malloc(sizeof *item);
*item = (Item) {
    .name = "job",
};

Your first method is incorrect (even without the typo) as you just discard the just malloced memory. You wanted to write Item = _item;

Upvotes: 3

Related Questions