Allocating a struct and saving a string in it - c

I'm having issues with getting create to hold firstE here:
struct node {
char * data;
struct node * next;
};
struct node * createList(char * firstE){
struct node *create;
create = malloc(sizeof(struct node));
create->data = malloc(sizeof(struct node));
strcpy(create->data, firstE);
create->next = NULL;
return create;
}
I'm having a problem with the memory allocation for create->data. I am trying to get it to hold the value of FirstE but I can't seem to get it.

I have to guess your problem since there is no struct definition. Your second malloc allocates memory for a field of the same type as the struct. But because you use strcpy to copy from the function argument, I suggest this line is incorrect, it allocates the wrong amount of memory
create->data = malloc(sizeof(struct node));
strcpy(create->data, firstE);
Since you copy the string argument to this field, I suggest this
create->data = malloc(1 + strlen(firstE));
strcpy(create->data, firstE);
The 1 + is to allow for the string terminator.

Related

Why don't we use calloc() insted of malloc() while creating linked list in C? [duplicate]

This question already has answers here:
Difference between malloc and calloc?
(14 answers)
Closed 2 years ago.
When we create a Linked List in C. In that, we have to allocate memory Dynamically. So we can use malloc() and calloc(), but most of the time programmers use malloc() instead of calloc(). I don't understand why?
This is a node -
struct node
{
int data;
struct node *next;
};
Now we are intinalizing the ptr -
struct node *ptr = (struct node *)malloc(sizeof(struct node));
Now here we are using malloc() So why most of the programmers don't use calloc() instead of malloc(). What difference does it make?
Consider a more realistic scenario:
struct person {
struct person *next;
char *name;
char *address;
unsigned int numberOfGoats;
};
struct person * firstPerson = NULL;
struct person * lastPerson = NULL;
struct person * addPerson(char *name, char *address, int numberOfGoats) {
struct person * p;
p = malloc(sizeof(struct person));
if(p != NULL) {
// Initialize the data
p->next = NULL;
p->name = name;
p->address = address;
p->numberOfGoats= numberOfGoats;
// Add the person to the linked list
p->next = lastPerson;
lastPerson = p;
if(firstPerson == NULL) {
firstPerson = p;
}
}
return p;
}
For this example, you can see that calloc() may cost CPU time (filling the memory with zero) for no reason at all because every field in the structure is set to a useful value anyway.
If a small amount of the structure isn't set (e.g. numberOfGoats is left as zero), then it's still likely to be faster to set that field to zero instead of setting the whole thing to zero.
If a large amount of the structure isn't set, then calloc() can make sense.
If none of the structure is set, then you shouldn't have allocated memory for nothing.
In other words; for most scenarios, calloc() is worse (for performance).

Storing a string in struct via an argument to a function

I'm struggling to figure out how to pass a string into a function and then how to store it in struct via pointer. I want to create a linked list where each node contains a node name(string) and data(integer) representing the weight required to reach that node.
The structure representing the node is as follows:
struct ListNode
{
// The energy required to reach in this node
int data;
// The name of the node
char location[20];
// And the nodes along side this one
struct ListNode* next;
struct ListNode* prev;
};
The following function generates a node and sets its next and previous pointers:
// Allocate a new listNode with the provided value
struct ListNode* listNodeConstructor(int value, char *city)
{
struct ListNode* newNode;
// Reserve memory for a node
newNode = malloc(sizeof(struct ListNode));
// Set its values
newNode->data = value;
newNode->name = strdup(city); /* This is how I've tried to implement it but it causes an error */
newNode->next = NULL;
newNode->prev = NULL;
// And return it
return newNode;
}
If anyone can show me how to correctly store the string in the node struct, I would be eternally grateful.
strdup() copies a string to a newly malloced place in the heap and returns a pointer to the new string.
Note that you also need to free it.
The problem is, that the string you want to set is part of the structure and not just a pointer you can set.
You have two options:
Use strcpy(newNode->name,city); instead of newNode->name = strdup(city);. This copies the city string to newNode but you need to assure that city has a \0 until newNode->name overflows.
change name to be just a pointer and free it when you free the node. You can use strdup in that case. (Change char location[20]; to char *location;
You cant assign arrays. You can only assign scalar variables or structs or unions
struct ListNode
{
// The energy required to reach in this node
int data;
// The name of the node
char *name;
char name1[32];
struct ListNode* next;
struct ListNode* prev;
};
int foo(struct ListNode *node, const char *str)
{
node -> name = str; // but remember that it only assigns the
//reference and does not copy the string
/* OR */
node -> name = strdup(str); // but remember to free it
strcpy(node -> name1, str);
}
You are attempting to use strdup (3) which creates a copy of the string in a newly heap allocated space. You are therefore attempting to assign a pointer (which is the return of your strdup to a char array. As you already have allocated your string space in your structure, you should therefore use strcpy (3) instead in the following way: strcpy(newNode->name, city).
Also please note it is always a good practice to pass pointer parameters as const when you do not intend to modify them. This convention aims to improve readability and is very helpful when you want to debug your programs when they grow bigger.

Implementing a simple linked list in C without malloc

All the implementations I have seen online use pointer to declare nodes and then will use malloc to create space for them like this:
struct Node
{
int data;
struct Node *next;
};
int main()
{
struct Node* head = NULL;
struct Node* second = NULL;
struct Node* third = NULL;
head = (struct Node*)malloc(sizeof(struct Node));
second = (struct Node*)malloc(sizeof(struct Node));
third = (struct Node*)malloc(sizeof(struct Node));
...
But I can also create the same without pointers and malloc like this:
struct node {
int id;
struct node* next;
};
struct node head = {0, NULL};
struct node one = {1, NULL};
struct node two = {2, NULL};
struct node tail = {3, NULL};
int main(){
head.next = &one;
one.next = &two;
two.next = &tail;
...
My question is, why the 1st method is mostly the one used, why do we need to declare each node as pointer and why do we need malloc?
(Just to point out I know why struct Node *next; is declared as pointer int the struct declaration).
You should do this with local variables, not global ones, but the general idea would be the same. You should also steer towards having arrays and not heaps of otherwise unrelated variables:
struct node {
int id;
struct node* next;
};
int main(){
struct node nodes[4];
for (int i = 0; i < 4; ++i) {
nodes[i].id = (3 - i);
if (i != 0) {
nodes[i].next = &nodes[i-1];
}
}
return 0;
}
Where something like that assembles them in reverse order for convenience, but they're all grouped together in terms of memory initially.
malloc is used because you often don't know how many you're going to have, or they get added and removed unpredictably. A general-purpose solution would allocate them as necessary. A specialized implementation might allocate them as a single block, but that's highly situational.
Here the lifespan of nodes is within that function alone, so as soon as that function ends the data goes away. In other words:
struct node* allocateNodes() {
struct node nodes[10];
return &nodes; // Returns a pointer to an out-of-scope variable, undefined behaviour
}
That won't work. You need a longer lived allocation which is precisely what malloc provides:
struct node* allocateNodes() {
struct node *nodes = calloc(10, sizeof(struct node));
return nodes; // Returns a pointer to an allocated structure, which is fine
}
The problem is if you malloc you are responsible for calling free to release the memory, so it becomes more work.
You'll see both styles used in code depending on the required lifespan of the variables in question.
If you know ahead of time exactly how many items will be in your list, then you're probably better off using an array rather than a list. The whole point of a linked list is to be able to grow to an unknown size at runtime, and that requires dynamic memory allocation (i.e., malloc).

Creating a link in linked lists in C

Here is the code to create a link in the list which i read off the internet to try understand linked lists in c:
//insert link at first location
void insertFirst(int key, int data) {
//create a link
struct node *link = (struct node*) malloc(sizeof(struct node));
link->key = key;
link->data = data;
//point it to old first node
link->next = head;
//point first to new first node
head = link;
}
I am really not understanding how the following line works as a whole:
struct node *link = (struct node*) malloc(sizeof(struct node));
and more specifically:
(struct node*)
because my understanding is that the asterisk must come before the pointer name and yet its at the end of the struct name. Please correct me if I'm wrong and please if you can, explain how this works?
Casting the return value of malloc is unnecessary.
As per standard 7.22.3.4
The malloc function returns either a null pointer or a pointer to the
allocated space.
You should check its return value to know whether it succeeded or not.
What malloc does?
The malloc function allocates space for an object whose size is specified by size and whose value is indeterminate.
my understanding is that the asterisk must come before the pointer name and yet its at the end of the struct name
Here you are not dereferencing anything. Rather you are typecasting. (which is again I would repeat that unnecessary).
struct node* here is a type of the pointer variable. Same way int or double is a type, this is also a type.
Assume you have to create database of a students having some entities.
struct node
{
int id;
char name [100];
};
Next thing,
struct node *link = (struct node*) malloc(sizeof(struct node));
How above line works ? you need to create one node or memory, So how will you create it, use malloc(). Next things how much memory you are going to create , equal to total size of your data members of structure, so for that its using
struct node *link = malloc(sizeof(struct node));
here link is nothing but name of dynamic memory we created to put some data into that. once memory is created put some data into memory.
scanf("%d %s\n",&link->id,link->name);
similarly you can do above task no of times.
typecasting is not compulsory or not advised to do. So below statement is correct.
struct node *link = malloc(sizeof(struct node));
In order to create a linked list you have to allocate the units -in your case :
struct node
so either you pre-allocate the memory for the list or dynamically allocate them every time you add a node to the list, the memoery for the node has to be recruited from somewhere, in this case - malloc does that.
Hope that helps

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.
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.
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?
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.

Resources