Kyon Bugsy
Kyon Bugsy

Reputation: 33

Allocating memory for structures in c

struct data{
char *key;
char *fname;
char *lname;
char *grade;
struct data *next;
};


 newnode = (struct data*)malloc(sizeof(struct data));
 strcpy(newnode->lname,lname);
 strcpy(newnode->grade,grade);
 strcpy(newnode->key,key);
 strcpy(newnode->fname,fname);
 newnode->next=NULL;

So i was working on hashtables. The above code crashes while

struct data *newnode;
newnode = (struct data*)malloc(sizeof(struct data));
newnode->lname=(char*)malloc(strlen(lname)+1);
newnode->fname=(char*)malloc(strlen(fname)+1);
newnode->grade=(char*)malloc(strlen(grade)+1);
newnode->key=(char*)malloc(strlen(key)+1);

strcpy(newnode->lname,lname);
strcpy(newnode->grade,grade);
strcpy(newnode->key,key);
strcpy(newnode->fname,fname);
newnode->next=NULL;

this code seems to run. Why is that? As far as i understand i've already allocated memory for my struct in the heap. Why would i have to do it for each object specifically? Is there something else im missing? Cause i really don't understand why the bottom example would work.

Upvotes: 1

Views: 112

Answers (3)

simo-r
simo-r

Reputation: 733

When you malloc a structure with char * inside it doesn't point anywhere (at least is NULL) so you've to malloc it as a normal sequence of characters also because you must know the size of the destination string. You can do it in your way using malloc and strcpy or just strdup.

Upvotes: 0

Stephan Lechner
Stephan Lechner

Reputation: 35154

With newnode = (struct data*)malloc(sizeof(struct data)), you allocate memory only for struct data, which is a set of pointers, but you do not allocate any memory for that where these pointers are pointing to and where you will copy your strings to. So you have to allocate memory for each string separately, either by using malloc as in the second part of your question, or by using strdup, which does malloc and strcpy in one command:

struct data{
char *key;
char *fname;
char *lname;
char *grade;
struct data *next;
};


 newnode = (struct data*)malloc(sizeof(struct data));
 newnode->lname = strdup(lname);
 newnode-> grade = strdup(grade);
 newnode-> key = strdup(key);
 newnode-> fname = strdup(fname);
 newnode->next=NULL;

It's worth noting that strdup requires a string as input, i.e. a pointer that is not NULL and that points to a \0-terminated sequence of characters.

Upvotes: 4

Some programmer dude
Some programmer dude

Reputation: 409176

When you do

newnode = malloc(sizeof(struct data));

you only allocate memory for the actual structure. But since the structure contains pointers, you need to make those pointers point somewhere valid. The single malloc call doesn't know anything about the contents of the structure, or how much extra memory it should allocate for all the pointers.

If, for example, you declare a single normal pointer variable you would not expect to be able to just use it as a destination for a strcpy call without allocating memory, would you?

Upvotes: 4

Related Questions