BC906
BC906

Reputation: 11

C - how to malloc struct containing string and array?

say, I have some struct like this:

typedef struct node {
    char[32] name;
    int *contents[10];
} Node;

I want to initialize a new Node and store it on heap, do I need also to malloc space for name and integers? However, if I tried to malloc space for them, for example:

Node *new_node = malloc{...};
new_node->name = malloc{32 * sizeof(char)};
...

I got error says name is not assignable.

Upvotes: 0

Views: 2886

Answers (3)

Toby Speight
Toby Speight

Reputation: 30728

The usual idiom is

Node *new_node = malloc(sizeof *new_node);

This ensures that the space allocated sufficient for new_node, even if you change its type. If you use sizeof (Node) instead, you are prone to the mistake of changing the type of new_node and failing to update the sizeof expression.

Your code

node->name = malloc(32 * sizeof(char));

will not compile because node->name is not a pointer type; it's an array within the Node type, and the storage is allocated when you malloc() for new_node above. So you can just go ahead and use that storage.

Note that sizeof (char) is 1 by definition, and the above would normally be written

node->name = malloc(32);  // still can't assign to node->name, though!

Upvotes: 0

dbush
dbush

Reputation: 223719

When you allocate space for your struct as Node *new_node = malloc(sizeof(Node));, that includes space for each struct element.

In this case, that includes space for 32 char and 10 int *. So you don't need to allocate space for the name array, although depending on your usage, you might allocate space to each element of contents.

Upvotes: 1

Iharob Al Asimi
Iharob Al Asimi

Reputation: 53006

To avoid confusion, and to make the code maintainable do it like this

Node *new_node = malloc(sizeof(*new_node));
if (new_node == NULL)
   allocation_error_do_not_continue();

if you check sizeof(*new_node) which is the same as sizeof(Node) would be 10 * sizeof(int *) + 32 sizeof(char) although sizeof(char) is always 1 so 10 * sizeof(int *) + 32.

Not that this requires the definition of the structure to be avaliable in order for the sizeof operator to be able to give the size of the structure.

Also, you suggest to malloc() for the name member, the name member is an array and you cannot assign to it, it has enough space for a 31 character string which you can use by assigning to each element, or using strcpy()/memcpy() to copy a complete array to it. But you can't assign to it and you don't need to malloc() space for it because malloc()ing the structure already malloc()ed both arrays.

Upvotes: 1

Related Questions