Program crashing due to printf statement C - 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 :)

Related

When pointer points to structure location in memory how can we access structures fields just through that address?

Im new to community this is my first post so hello to everyone.
I have recently started studying the coding and c language in specific.But i have a confusion when it comes to structures and how they are referenced in memory.
This is example when my lack of understanding makes me unable to understand what exactly happening in code.
For example when asking malloc for space for lets say a node structure the way i understood it until now is that computer will allocate memory of size of struct if instructed by size of operator in parenthesis. Therefore that many memory locations will be allocated starting at specific location pointer points to.But when we use pointer of struct type we allocated memory for (in this case struct node) it just stores a address of first byte of said struct as all pointers do if i understand correctly.
Then when
`*(pointername).exactfieldname
For example if we assume there is node structure defined in code.With two fields for int called numbers and for pointer called next.
node *n=malloc (sizeof(node));
*(n).next=malloc (sizeof(node));
syntax is used i cant understand how it works exactly.How is a computer just through pointer to a first byte out of certain number of bytes that were allocated suddenly able to access fields of structure?
Reason this is additionally confusing is because when defining a node struct for linked list for example it is possible to define pointer to struct of struct type being defined before it is defined because its just a pointer so it only stores address. Due to that fact struct pointer cant have any special property allowing it to access fields its still just a pointer right?
When pointer is derefrenced does it mean that computer goes to pointed location and enters a strucutres. And then rest of syntax after dereferencing pointer like *(pointer ).fieldname can be used because now computer is inside structure and interacts with it and .fieldname refers to that instruction now?
I'll try to answer despite your question lacking some clarity.
If I get you right, you are confused by this:
typedef struct node {
struct node *next; // <<<< here
some_type_t data;
} node;
In the line marked, the compiler does not yet know what struct node looks like.
That is correct. It doesn't need to know that because we only store a pointer.
In that place you cannot define a non-pointer element of that type (or any other incomplete type) for exactly that reason.
Now if you come to that part:
node *n=malloc (sizeof(node));
n->next=malloc (sizeof(node));
(Note: Your syntax was incorrect)
You seem to wonder how the compiler would know what n->next really is as it was unknown when the struct was defined.
That does not matter.
It is known when the compiler comes to this line. You can only dereference a pointer if the type is fully known in that location.
The compiler now knows what node* means and can address the fields in *n and in the same way it can deal with n->next.
Study and try do understand the following code.
Compare the values that are printed out. %p will print address values (hex format) and %d prints decimal values.
Take a good look at the parameters that are passed to the printf function. & is the 'address of' operator and -> is a dereference operator, which is equal to *(pointer)..
struct node {
struct node *next; //pointer to struct node
struct data_rec { //embedded struct
int value; //some value of type int
} data; //data of type struct data_rec
};
//allocation on the heap -> pointer to struct node
struct node *allocated_node = malloc(sizeof(struct node));
allocated_node->next = NULL;
allocated_node->data.value = 0;
//allocation on the stack (sizeof(struct node) bytes)
struct node base_node;
base_node.next = allocated_node;
base_node.data.value = 42;
//prints some information of the node
void printNodeInfo(struct node *node_)
{
printf(
"address of node: %p\n"
"address of node.next: %p\n"
"value of node.next: %p\n"
"address of node.data: %p\n"
"address of node.data.value: %p\n"
"value of node.data.value: %d\n",
node_,
&node_->next,
node_->next,
&node_->data,
&node_->data.value,
node_->data.value
);
}
int main()
{
printNodeInfo(&base_node);
printNodeInfo(allocated_node);
return 0;
}

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.

How do you store string type data in a linked list in C?

So I'm trying to understand how a linked list works with storing string type pieces of data. As far as I know, a linked list uses a data structure to store data in a somewhat fashionable way so you can easily enter new pieces of data inside, remove them, and rearrange them as you please. My problem is, I need to take a string in from the user, assign it a spot in the linked list and move on to the next node in the list and do the same thing again. At this point however, I'm simply trying to take one string from the user, store it in the new_node value, (or (*new_node).value for those of you thinking in terms of pointers and not linked lists) and print it out. The main just asks the user for a string input, the add_to_list func takes the input and adds it to the beginning of the linked list, and the print func simply prints what ever is in the linked list. Where the problem lies in my understanding (at least what I think is the problem) is the point at which I assign the data structure the value of the input, new_node->value=*n should just make the value contain the input string as it would just giving another array the value of whatever the pointer *n is containing, unfortunately that's not the case and I'm not sure why that is. Here's the code for simplicity's sake.
EDIT: Thanks everyone for the responses and the explanation behind why strcpy is necessary when dealing with assigning the value of an array of characters to another array ie: strings!
#include <stdio.h>
#include <stdlib.h>
#define LARGE 10
struct node *add_to_list(struct node *list, char *n);
struct node{
char value[LARGE+1];
struct node *next;
};
struct node *first = NULL;
void print(void);
int main(void) {
char job[LARGE],*p;
printf("Please enter printing jobs\n");
scanf ("%s", job);
p=&job[0];
first = add_to_list(first, p);
print();
return 0;
}
struct node *add_to_list(struct node *list, char *n)
{
struct node *new_node;
new_node = malloc(sizeof(struct node));
if (new_node == NULL) {
printf("Error: malloc failed in add_to_list\n");
exit(EXIT_FAILURE);
}
new_node->value = *n;
new_node->next = list;
return new_node;
}
void print(void){
struct node *new_node;
for(new_node=first;new_node!= NULL; new_node=new_node->next){
printf("%s\n",new_node->value);
}
}
Use strcpy instead of assigning a char to an array, which doesn't compile. Arrays are not lvalues, and cannot be assigned to without subscripting, so any assignment with an array name by itself on the left will not compile. Change
new_node->value = *n;
to
#include <string.h>
...
strcpy(new_node->value, n);
you cannot assign string as normal integer assignment.
whenever you want to copy a array you have to use library functions like memcpy or strcpy. In your case its array of characters i.e string you have to use strcpy.
usage char *strcpy(char *dest, const char *src);
so in your code it has to be like strcpy(new_node->value,n); instead of new_node->value=*n;
Reason for using strcpy is mentioned in the link below
why strcpy function

Remove even numbers from queue

I got stuck when trying to remove even number from queue in C programming. Here is the code:
My data structure for Queue:
typedef struct _listnode
{
int data;
struct _listnode *next;
} ListNode; // You should not change the definition of ListNode
typedef struct _linkedlist
{
int size;
ListNode *first;
} LinkedList; // You should not change the definition of LinkedList
typedef struct _queue
{
LinkedList list;
} Queue;
And I am calling from my main:
case 3:
deleteEven(&q); // You need to code this function
printf("Result:\n");
printList(&q.list);
break;
What I am trying to do is first, I tried to check if the queue is empty. Then I will get the linked list head and modulus with 2, if getting 0 means it's even number and then I will dequeue it from the queue.
However, with these code, when I try to dequeue even numbers from queue, it just stopped working and not showing any error message.
Anybody know how to solve this? Thanks in advance.
In your function deleteEven's while loop you do this -
free(odd->list.first->data); //problem 1
odd->list.first->data= odd->list.first->next; //problem 2- assigning pointer type to int
Problem 1- But you haven't allocated memory to odd->list.first->data , it is an integer variable. And if you try to free such thing can cause error in your program (you should not free memory not allocated by malloc or similar functions)
You allocate memory to odd , so free pointer odd.
Even you should not free inside your while loop, as you allocate memory only one time .
Problem 2 - You assign pointer type to int. That's may also be one of reason for this error .
You should write loop like this -
while (!isEmptyQueue(odd)) {
enqueue(que, odd->list.first->data);
odd->list.first= odd->list.first->next; // increment pointer
}
free(odd);
3. While calling function dequeue -
dequeue(que->list.first->data);
int is passed but it expects Queue * .
Its type is int but you return NULL from it (return -1 or something to show failure).

pointer to pointers for singly linked list in C [duplicate]

This question already has answers here:
What is the reason for using a double pointer when adding a node in a linked list?
(15 answers)
Closed 9 years ago.
I have a question about signly linked lists in C. I've created a linked list with the code shown below :
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node* next;
};
struct node *mknode(int data)
{
struct node* np=malloc(sizeof(struct node));
np->data=data;
np->next=NULL;
return np;
}
struct node * insert (struct node* list,int data)
{
struct node *np;
struct node*curr=list;
struct node* prev=NULL;
np=mknode(data);
for(;curr &&data<curr->data;curr=curr->next )
prev=curr;
np->next=curr;
if(prev)
prev->next=np;
else
list=np;
return list;
}
int main()
{
struct node* head;
head=malloc(sizeof(struct node));
head=insert(head,7);
head=insert(head,2);
head=insert(head,4);
printf("%d",head->data);
printf("%d",head->next->data);
printf("%d",head->next->next->data);
return 0;
}
However,While I search on internet, I've realized that, the double pointer is used for creating linked list instead of a normal pointer.I mean, struct node **list , not struct node * list . I wonder why ? Which one is correct , and If both of them is true , what is the differences between them, I used my implementation with the sample main I wrote here, and it works fine but I dont know why should I use pointer to pointers ? Thanks in advance.
The reason some people use a pointer to a pointer is so that the nodes can be updated without returning a new pointer. In your example, if you wanted to change the head pointer, you would have to create a new pointer and then make head equal to that pointer. With the double pointer, you only have to free the space that the second pointer points to, and then update the second pointer to your new data structure, which keeps your original head pointer
I just use the single pointer in my implementations.
Read here, In this way you can change elements without creating new ones.
What is the reason for using a double pointer when adding a node in a linked list?
Given
struct node { int x; };
struct node **pplist;
struct node *plist;
pplist is a pointer to a pointer to a struct node, while plist is a pointer to a struct node. To change x, you would need to write
*pplist->x = 3;
plist->x = 4;
You would use a pointer to a pointer if you wanted the same variable to point to, say, different lists, or if you wanted to pass a pointer to a function with a side-effect of changing that pointer.
This looks perfectly fine to me.
All a pointer is, is a memory address to somewhere. A double pointer is just a memory address to another memory address which points to some data.
Maybe you can post where you saw node **list and we can explain it better but for now, your code looks good.
it is a bit of naturally, if you call "head = NULL; insert(&head, data);" that then head points to the first element. All functions, that supose to change the content, should be called indirectly.
BUT: this is a matter of coding convention. Some like it hot, some like it cold. The problem with head=insert(head, data); is, that head is unusable, when you forget "head="

Resources