Having error when pushing global linked list *sometimes(randomly)* - c

I created a global linked list. It doesnt work sometimes. First push is always succesfully done but second push makes error sometimes. I tried on another computer but its same.
typedef struct person{
char name[20];
char surname[20];
char musical_Work[20];
int age;
struct person *next;
}*top;
top head=NULL; /* GLOBAL */
void addNode( /* datas */ ){
top new_node=(top)malloc(sizeof(top));
/* copying datas */
new_node->next=head;
head=new_node;
}

The code top new_node=(top)malloc(sizeof(top)); allocates enough space for a top, which is a pointer to struct person. However, the space is going to be used to hold struct person, and therefore it must allocate enough space for struct person. Therefore, correct code for this is:
top new_node=(top)malloc(sizeof(struct person));
Additionally:
Using sizeof *new_node automatically allocates enough space for whatever new_node points to, even if the type of new_node is changed as the code is edited.
In C, there is no need to cast the type of malloc. This code can be top new_node = malloc(sizeof *new_node);.
Consider using a different name for a pointer to struct person, instead of top. It is not always the top of the stack.

Related

try to malloc a struct array, but get heap buffer overflow

I am new to programming and have just learned C shortly. Now my problem is, i tried to malloc a struct array, and then use it to fill in some information. but keep getting the heap overflow error report.
here is my declaration of struct in the h.file.
typedef struct llnode {
char llnodename[256];
int ll_index;
struct llnode* next;
} llnode;
//the struct of a linked list.
typedef struct node_stru {
char nodename[256];
int node_index;
} node_stru;
//the struct of the node.
and the pointer:
node_stru *node_list = (struct node_stru*)malloc(n_nodenumber*(sizeof(node_stru)));
but later when i wants to use the linked list to fill in some information,it give me the heap overflow.
llnode* ptr=Ahead;
while (ptr!=NULL){
printf("the name%s, the index%d", ptr->llnodename, ptr->ll_index);
strcpy(node_list[n_index].nodename, ptr->llnodename);
node_list[n_index].node_index = ptr->ll_index;
n_index++;
ptr = ptr->next;
}
The error report: I do malloc a 4*(256+4) memory, but it still not working.
0x619000000490 is located 0 bytes to the right of 1040-byte region [0x619000000080,0x619000000490)
You've allocated a fixed size for node_list, but there's nothing stopping your loop from walking off the end. For example, if n_nodenumber is 4 you can store 4 nodes. But if Ahead is linked to 5 nodes it will walk off node_list. That's assuming n_index starts at 0.
At minimum your loop should assert(n_index < n_nodenumber) to provide a better error when the loop walks off the array. That's all I can say without seeing a complete example.

Program crashing due to printf statement C

I created a program that uses pointers and nodes for a linked list. I narrowed down the problem to the following lines of code. Every time my program reaches the printf section it crashes.
typedef struct book {
char title[50];
char author[50];
}BOOK;
typedef struct Node {
struct Node* next;
BOOK info;
int priority;
}node;
I narrowed down the problem to the following lines of code. Every time my program reaches the printf section it crashes.
void peek(node **head) {
node *temp = *head;
printf("%s by %s has been peeked.",temp -> info.title , temp -> info.author);
}
Any help is greatly appreciated!
EDIT :
in my main i have:
BOOK bookDetails() {
BOOK b;
printf("\nEnter book title: ");
fflush(stdout);
scanf("%s", b.title);
printf("\nEnter the author: ");
fflush(stdout);
scanf("%s",b.author);
return b;
}
..and in the main(void):
node *queue = NULL;
case 4: peek(&queue);
break;
In other cases i added information into &queue using BOOK b to link to struct book
bookDetails()
your BOOK b; goes out of scope at the end of bookDetails();
you would be wise to ether:
pass a pointer to a BOOK struct into bookDetails
you would need to change your return type to int and use it for error checking.
dynamically allocate some heap memory inside bookDetails() with malloc() for that
book struct.
requires #include and free() when you are done with the memory.
main(void)
what this line does node *queue = NULL;
in English:
allocate a new pointer on the stack to a node struct then, set the pointer to NULL.
when you pass this to peek naturally you will get some errors because you cannot deference a NULL pointer.
struct Node and queue
you have the beginnings of a linked list structure with Node but, then I see you using this pointer to pointers queue. Unless you would like more than one linked list I would say removing the queue pointer would be a good thing to do to reduce the complexity.
peek()
here I do like what you did to do away with the need for all those paren but on first glance node *temp = *head; looks like temp == head which is far from the truth
why it is crashing recap
what peek says it does (in english):
peek takes a pointer to a pointer to a node struct
peals off the first pointer to a node
differences that pointer (with the "->" notation)
print to standard out.
substitute in what we pass to peek (in english):
peek receives NULL(0x0)
create a node struct pointer named temp and put NULL inside the pointer.
Attempt to access the address 0x0 (with the "->" notation)
segfault.
If you have any questions just ask.
Good luck :)

Linked-list is confusing

I am stuck, as I don't understand what is this code doing:
struct node
{
int info; /* This is the value or the data
in the node, as I understand */
struct node *next; /* This looks like a pointer. But
what is it doing in real life? */
} *last; /* What is this and why is it
outside the body? What is this
thing doing? */
I know that when a node is created, it has a value, and it is pointing to some other node
but I don't understand the syntax.
Is this a better way of writing the code above?
Is there a simpler way of writing the same struct for better understanding?
In my lectures they presume that the student has understanding of what they teach.
Well, we can explain this to you, but we can't understand it for you.
Code snippet you've provided is definition of variable last, being pointer to newly defined structure type node. It can be written other way as:
typedef struct _node_t {
int info;
node_t *next;
} node_t;
node_t *last;
This way we define typedef, which is, say, alias of type definition to some short name — in this particular case, it aliases structure of two fields as the name node_t. Wherever you define something as being of type node_t, you tell compiler that you mean 'this should be aforementioned structure of two fields', and node_t *last means 'variable last should be pointer to node_t type'.
So, back to syntax:
struct foo {
int a;
float b;
void *c;
} bar, *baz;
means 'Define structure type foo, and make it contain three fields — integer a, float-point b and untyped pointer c, then make variable bar to be of this structure type, and make variable baz to point to this structure type'.
Now to pointer. What you see is called 'recursive definition', e.g. type mentions itself in it's own definition. They are okay, if language supports them (C does), but one could avoid recursive definitions in linked list node structure by specifying next node pointer to be just untyped:
struct node_t {
int info;
void *next;
};
This way you no longer reference node_t type from node_t type, but that adds you some inconveniences when using this type (you have to explicitly cast next to node_t type, like ((*node_t)(last->next))->info instead of just last->next->info).
If you feel you need additional reference, consider taking a look at interactive online tutorials, like http://www.learn-c.org/ (I'm not affiliated).
that is the simplest way to write a linked list node , but why name it last ? name it node instead , this makes it more understandable , but here's how it works.
when a linked list is first created it contains only the root node (the first node in a linked list) , when you add a node , you fill the info field with the data that node will hold (note that info may be any kind of data , character , string , int ...) then set next to NULL , since that node is the last node in the list.
when you add another node , you change the value of next to point to the node you just added and you set the value of next to NULL in the node you just created because now that is the last node in the list .
you can repeat this to add as many nodes as your memory allow you to.
this link may help you to better understand structures
typedef struct marks {
int m;
struct marks *next;
} marks_t;
This way we define a structure so that a Linked List can be formed. Now we have defined the last variable next as a "structure pointer" which gives us the address of the next element in the list (i.e. as structure only)!
The last element does not point to any node (here marks structure) and hence the pointer variable has NULL value.
Now to define the first element:
marks_t *list;
if (list == NULL) {
list = (marks_t *) malloc(sizeof(marks_t));
}
list->m = 15;
list->next = NULL;
Now if we want to add an element next to this (i.e. second element):
marks_t *next1;
next1 = (marks_t *) malloc(sizeof(marks_t));
next1->m = 27;
next1->next = NULL;
list->next = next1; // Storing address of next1 structure in list

how to copy struct data in C language?

I'm still having trouble understanding how to copy structs that include char* fields\other struct fields:
typedef struct node{
int id;
struct node* parent
char * nodeName;
struct node* nodes[100];
}NODE,*pNODE;
I want to use this function : pNODE copyNode(pNODE oldNode)
1. i know that first I should do allocation for the new pointer data , and do the followong:
pNODE newNode = (pNODE)calloc(1,sizeof(NODE));
newNode.id=oldNode.id
//for the string that I want to copy I should allocate and use strcpy - in order not to point at the same string
but now I'm lost regarding the parent node, how do I copy it ? if I just do : newNode.parent=oldNode.parent
I point at the same parent object, and if I change it's Id for example - it will change both the id of newNode and oldNode. how can I copy it?? without pointing at the same one?
and how can i copy the pointer array??
thank you!
Take a look at the memcopy function:
memcpy(oldNode.parent, newNode.parent, sizeof(node)).
Of course, you first need to allocate memory for the newNode's parent, using malloc (calloc doesn't make sense in this context - it's used for arrays)
newNode.parent = (NODE*)malloc(sizeof(NODE))
If you want to do a deep-copy (i.e. don't reuse referenced objects), you should go through the newNode struct and allocate memory for each pointer contained in the struct and then apply memcopy.

How to use a struct in C?

This is code for a linked list in the C programming language.
#include <stdio.h> /* For printf */
#include <stdlib.h> /* For malloc */
typedef struct node {
int data;
struct node *next; /* Pointer to next element in list */
} LLIST;
LLIST *list_add(LLIST **p, int i);
void list_remove(LLIST **p);
LLIST **list_search(LLIST **n, int i);
void list_print(LLIST *n);
The code is not completed, but I think it's enough for my question. Here at the end of struct node "LLIST" is used, and it's also used as a return type in the prototyping of the function list_add. What is going on?
That's a typedef. It's actually doing two things at once. First, it defines a structure:
struct node {
int data;
struct node *next;
}
And then does a typedef:
typedef struct node LLIST;
That means LLIST is a type, just like int or FILE or char, that is a shorthand for struct node, your linked-list node structure. It's not necessary - you could replace LLIST with struct node in all of those spots - but it makes it a bit easier to read, and helps hide the implementation from pesky end-users.
LLIST is just another type name for the struct that has been created. In general, the following format will create a type "NAME" that is a "struct x":
typedef struct x { ... } NAME;
C requires that you reference structs with a "struct" prefix, so it's common to introduce a typedef for less verbose mention.
That is, the declaration of your struct has two parts, and can be rewritten as such:
struct node {
int data;
struct node *next; /* pointer to next element in list */
};
typedef struct node LLIST;
So, LLIST is just another name for struct node (thanks Chris Lutz).
typedef creates a new "type" in your program, so the return value and types of parameters of those functions are just your struct. It is just shorthand for using struct node for the type.
If you were to create a new node, you could do it like this (using the type):
LLIST *node = malloc(sizeof(LLIST));
node->data = 4;
node->next = someOtherItem;
list_add(node, 1)
Also, with the function prototypes in your question, you don't really need the double pointers; since the data in your struct is just an int, you could do something like
LLIST *list_add(int data, int position);
then the list_add function would handle the allocation, copy the int into the struct and add it to the linked list.
Putting it in at a certain position is as simple as changing the next pointer in the node before it to the address of the newly allocated node, and the next pointer in the new node to point at the next one (the one the node before that one was originally pointing at).
Keep in mind that (given the rest of your function prototypes) you will have to keep track of pointers to every node you create in order to delete them all.
I'm not sure I understand how the search function will work. This whole thing could be implemented a lot better. You shouldn't have to provide the location of a node when you create it (what if you specify a higher number than there are nodes?), etc.
LLIST* is a pointer to a structure defined by the LLIST struct.
You should do
LLIST* myList = malloc(sizeof(LLIST)*number_of_elements);
to have some memory allocated for this list. Adding and removing items requires you to reallocate the memory using realloc. I've already written some piece of code for lists (made with arrays).
I might post the code as soon as I'm home, which is currently not the case.

Resources