Reputation: 33
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
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
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
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