here's my code in C for making of linked list. Its giving runtime error after the while loop gets executed for one time. Plz help me in correcting my code. (totally confused that where's the error.) I am making a head node first and then adding child nodes to it.
#include <stdio.h>
#include <stdlib.h>
typedef struct node nd;
typedef nd *link;
struct node{
int data;
link next;
};
typedef struct {
int size;
link head;
}list;
void create(link temp)
{
link new;
new=(link)malloc(sizeof(nd));
printf("enter data: ");
scanf("%d",new->data);
temp->next=new;
temp=temp->next;
}
list createlist()
{
list sl;
sl.size=0;
sl.head=0;
return sl;
}
int main()
{
list sl;
sl=createlist();
link temp;
temp=sl.head;
char c;
while (1)
{
printf("Add node?: ");
scanf(" %c",&c);
if (c=='y')
{
create(temp);
sl.size++;
}
else
break;
}
return 0;
}
your createlist() function is returning a reference to a local variable that goes out of scope after it returns. You should instead return a heap based value:
list* createlist() {
list* sl = (list*)malloc(sizeof(list));
sl->size=0;
sl->head=0;
return sl;
}
Initially temp points to NULL. temp = sl.head;
In create(temp) temp->next = new;
You are dereferencing a NULL, address 0x0. I get a segmentation fault when I do that.
Need to change the algorithm.
A debugger shows this problem immediately.
You could use a pointer to pointer for temp. It would be easier to read if you didn't use a typedef for a pointer to node. I haven't tested this, but it should be close:
nd ** create(nd **temp)
{
nd *new;
new=(nd *)malloc(sizeof(nd)); /* this cast shouldn't be needed */
printf("enter data: ");
scanf("%d",&(new->data));
new->next = NULL;
*temp = new;
return &(new->next);
}
/* ... */
int main()
{
nd **temp;
temp = &(sl.head);
/* ... */
temp = create(temp);
/* ... */
}
Related
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define SIZE 10
// A hashtable is a mixture of a linked list and array
typedef struct node NODE;
struct node{
int value;
NODE* next;
};
int hash(int);
void insert(int,NODE **);
int main(){
NODE* hashtable[SIZE];
insert(12,&hashtable[SIZE]);
printf("%d\n",hashtable[5]->value);
}
int hash(int data){
return data%7;
}
void insert(int value,NODE **table){
int loc = hash(value);
NODE* temp = malloc(sizeof(NODE));
temp->next = NULL;
temp->value = value;
*table[loc] = *temp;
printf("%d\n",table[loc]->value);
}
The above code prints :
12 and
27475674 (A random number probably the location.)
how do I get it to print 12 and 12 i.e. how to make a change in the array. I want to fill array[5] with the location of a node created to store a value.
The expression *table[loc] is equal to *(table[loc]) which might not be what you want, since then you will dereference an uninitialized pointer.
Then the assignment copies the contents of *temp into some seemingly random memory.
You then discard the memory you just allocated leading to a memory leak.
There's also no attempt to make a linked list of the hash-bucket.
Try instead to initially create the hashtable array in the main function with initialization to make all pointers to NULL:
NODE* hashtable[SIZE] = { NULL }; // Will initialize all elements to NULL
Then when inserting the node, actually link it into the bucket-list:
temp->next = table[loc];
table[loc] = temp;
This is just a simple change which I have made to your program which will tell you what you are actually doing wrong.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define SIZE 10
// A hashtable is a mixture of a linked list and array
typedef struct node NODE;
struct node {
int value;
NODE* next;
};
NODE *hashtable[SIZE] = { NULL };
int hash(int);
int insert(int); //, NODE **);
int main(void)
{
int loc = insert(12); //, &hashtable[SIZE]);
if (loc < SIZE) {
if (hashtable[loc]) {
printf("%d\n", hashtable[loc]->value);
} else {
printf("err: invalid pointer received\n");
}
}
return 0;
}
int hash(int data)
{
return data%7;
}
int insert(int value) //, NODE *table[])
{
int loc = hash(value);
printf("loc = %d\n", loc);
if (loc < SIZE) {
NODE *temp = (NODE *) malloc(sizeof(NODE));
temp->value = value;
temp->next = NULL;
hashtable[loc] = temp;
printf("%d\n", hashtable[loc]->value);
}
return loc;
}
Here I have declared the hashtable globally just to make sure that, the value which you are trying to update is visible to both the functions. And that's the problem in your code. Whatever new address you are allocating for temp is having address 'x', however you are trying to access invalid address from your main function. I just wanted to give you hint. Hope this helps you. Enjoy!
Please tell me why the segmentation error is there in my program there is no error .
I also tried to debug it but it never goes inside the for statement.
#include<stdio.h>
#include<malloc.h>
struct node
{
int data;
struct node* link;
} *start;
main()
{
int i,n,m;
start=NULL;
printf("enter the number of nodes you want");
scanf("%d",&n);
for(i=0;i<n;i++)
{
printf("enter the element you want to insert");
scanf("%d",&m);
create_list(m);
}
}
create_list(int data)
{
struct node *q,*temp;
temp=(struct node *)malloc(sizeof(struct node));
temp->data=data;
temp->link=NULL;
if(start==NULL)
start=temp;
else
{
while(q->link!=NULL) q=q->link;
q->link=temp;
}
}
You forgot to initialize q before using it:
q = start;
while(q->link!=NULL)
1.You haven't initialized q in create_list() and used it -
while(q->link!=NULL)
Intialize q=start; before this loop.
2.Also free the allocated memory for temp in function.
3.main() should be int main(void) and what is type of create_list? Declare its prototype before main.
In the function create_list local pointer q was not initialized
struct node *q,*temp;
^^^
However it is accessed in the loop
while(q->link!=NULL)
I think you mean the following
else
{
q = start;
while ( q->link != NULL ) q = q->link;
q->link = temp;
}
Take into account that the function should be declared before its usage. Place it declaration for example before main. And its return type shall be void and specified explicitly. Also function main shall have return type int.
For example
void create_list( int data );
int main( void )
{
//...
And it is a good idea to free all dynamically allocated memory before exiting the program.
Also header <malloc.h> is not a standard C header. You should use <stdlib.h> instead.
After all suggestions from the above it will be clearly in the future if you try to show some work of your clear codding and to respect the minimum standard.
Here is a way of how should be looking your code:
#include<stdio.h>
#include<stdlib.h> /* You need stdlib not malloc */
void create_list(int data); /* If you don't declare your function the compiler doesn't know nothing about create_list */
struct node{
int data;
struct node* link;
}*start;
int main(void){ /* Here return type of main is int and if no arg needed should be used void */
int i,n,m;
start=NULL;
printf("enter the number of nodes you want");
if((scanf("%d",&n)) != EOF) /* always check scanf's return */
for(i=0;i<n;i++){
printf("enter the element you want to insert");
if((scanf("%d",&m)) != EOF) /* here the same: always check scanf's return */
create_list(m);
}
return 0; /* return of main should be 0 or one of the following: EXIT_SUCCESS or EXIT_FAILURE, but 0 will be ok because it is standard*/
}
void create_list(int data){ /* here should be explicit what kind of function is */
struct node *q,*temp;
temp=(struct node *)malloc(sizeof(struct node)); /* if you allocate memory dynamically ..... */
temp->data=data;
temp->link=NULL;
if(start==NULL){
start=temp;
}else{
q = start;
while(q->link!=NULL){
q=q->link;
q->link=temp;
}
}
free(temp); /* .....then always free it */
}
I am trying basic creation of linked list using C. I have written the following code which is working up until first node but fails eventually on second one. I think the issue is where I am trying to display the node values in list separated by arrow(->). I think my logic is right but please correct me. Thanks in advance
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
struct node
{
int number;
struct node *next;
};
typedef struct node NODE;
NODE *node1, *node2, *start, *save;
int main()
{
node1 = (NODE *)malloc(sizeof(NODE));
int i = 0;
start = NULL;
for(i = 0; i < 3; i++)
{
int inf;
printf("Enter node value:");
scanf("%d", &inf);
node1->number = inf;
node1->next = NULL;
if(start == NULL)
{
start = node1;
save = node1;
}
else
{
// save=start;
// start=node1;
// node1->next=save;
node1->next = start;
start = node1;
}
while(node1 != NULL)
{
printf("%d ->",node1->number);
node1 = node1->next;
}
}
return 0;
}
The issues are
How you're allocating your nodes for insertion (i.e. save for one, you're not).
How they're placed in the list once you fix the above.
Don't cast malloc in C programs (read here for why).
Fail to check the success of your scanf invoke.
Fail to check the success of your malloc invoke
Before you get discouraged, things you did correctly:
Did not mask a node pointer in a typedef
Properly included a MCVE for review
Prospected the things you may be doing wrong.
A very simple example of iterating three values into a linked list would look something like this:
#include <stdio.h>
#include <stdlib.h>
struct node
{
int number;
struct node *next;
};
typedef struct node NODE;
int main()
{
NODE *head = NULL, *p;
int i = 0;
for(i = 0; i < 3; i++)
{
int inf;
printf("Enter node value:");
if (scanf("%d", &inf) == 1)
{
p = malloc(sizeof *p);
if (p != NULL)
{
p->number = inf;
p->next = head;
head = p;
}
else
{
perror("Failed to allocate new node");
return EXIT_FAILURE;
}
}
else
{
// failed to read data. break
break;
}
// report current linked list
printf("%d", p->number);
for (p=p->next; p; p = p->next)
printf(" -> %d", p->number);
fputc('\n', stdout);
}
// cleanup the linked list
while (head)
{
p = head;
head = head->next;
free(p);
}
head = NULL;
return 0;
}
Input
The values 1 2 3 are input upon being prompted:
Output
Enter node value:1
1
Enter node value:2
2 -> 1
Enter node value:3
3 -> 2 -> 1
Best of luck.
You should use malloc() inside for loop.
Since it is outside, same memory is being used.
As said by Vamsi, you should use malloc to put the nodes on the heap. You also generally shouldn't cast the output of malloc, it isn't needed. And then you could play around with making a doubly-linked list, where you also have a prev pointer inside your struct.
I've written an implementation of a doubly linked list with a .h prototype here and everything runs fine until I start entering values in the terminal. I get a segmentation fault after entering the second value, but, if I just use 1 value it executes normally. I've gone through it several times, but, I can't find my mistake. Could you guys help me find why I'm getting the error?
Here's the .h file:
#include <stdio.h>
typedef struct node Node;
struct node
{
int d;
Node *link;
}*head,*current,*prev;
int num_nodes;
void linked_list_init(int data);
void linked_list_sort();
void linked_list_print();
And here's the .c file:
#include "link.h"
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
void main(){
int n,e,i;
printf("How many numbers do you want to sort: ");
scanf("%d",&e);
for(i=0;i<e;i++){
printf("Enter number: ");
scanf("%d",&n);
linked_list_init(n);
}
linked_list_sort();
printf("The sorted numbers are: ");
linked_list_print();
}
void linked_list_init(int data){
Node *prev=0,*next=0;
current=(Node*)malloc(sizeof(Node));
if(head==0)
{
head=current;
current->d=data;
current->link=0;
prev=current;
}
else{
current->d=data;
current->link=0;
prev->link=current;
prev=current;
}
}
void linked_list_sort(){
int i,j;
Node *prev=0,*next=0;
current=head;
prev=head;
next=head->link;
for(i=0;i<num_nodes-1;i++)
{
for(j=0;j<num_nodes-i-1;j++)
{
if(current->d>next->d)
{
current->link=next->link;
next->link=current;
if(current==head)
{
head=next;prev=next;
}
else
{
prev->link=next;prev=next;
}
if(next!=0) //check whether final node is reached
next=current->link;
}
else //move each node pointer by one position
{
prev=current;
current=next;
next=current->link;
}
}
//next iteration
current=head;
prev=head;
next=current->link;
}
}
void linked_list_print(){
current=head;
while(current!=0){
printf("%d ",current->d);
current=current->link;
}
}
The problem is that you're masking the global variables with local declarations in your function. That means that the variable prev in the functions are not the same as the global variable prev.
Aside from that, you should never place variable definitions in header files, as those will clash with each other if the header file is included in multiple files.
There is also another small bug, in that you don't increase the counter when inserting a new node into the list.
There is no need to initialize head to 0 because in your case you have declared it globally in header file ( although its not a good practice to declare variables in header files). The problem here is you are redefining prev node in void linked_list_init(int data) function. Just delete the prev node from there and everything would work fine.
Tips:
-> Declare the head, prev, current nodes in .c file.
-> Use NULL instead of 0 or even you can use (void *) 0 instead of simply 0
It seems like you are creating and initializing *prev and *current everytime the linked_list_init function is called. Hence after you enter the second value, the second if loop is using prev, which has actually been set to 0.
I think what you are trying to do is use the *prev, *head and *current as global variables (since you have declared them in your header file). Just use extern to declare them in the source file and things should work.
The global variable used in your program are uninitialized and hence prone to garbage values . Also i suggest the following defination for your node
struct node {
int d;
node *llink; // Left Link
node *rlink; // Right Link
};
typedef struct node* Node;
Node head = NULL; // Head node
Also
void linked_list_init(int data) {
Node newnode = (Node) malloc(sizeof (Node));
newnode->d = data;
Node curr;
if (head == NULL) {
newnode->llink = NULL;
newnode->rlink = NULL;
head = newnode;
} else {
curr = head;
while (curr->rlink) {
curr = curr->rlink;
}
curr->rlink = newnode;
newnode->rlink = NULL;
newnode->llink = curr;
}
}
The above will keep adding elements to the end of the list .
You can print data out easily as follows :
void linked_list_print() {
Node curr;
curr = head;
while (curr) {
printf("Element Data : %d", curr->d);
curr = curr->rlink;
}
}
I've been trying to add a new node into a linked list of profiles (for ex. facebook profiles), and I'm getting a runtime error while launching. This is what I got :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
typedef struct friend {
char *name;
int age;
char gender;
struct friend* next;
} friend;
void node_add(friend* new);
int main(int argc, char *argv[]) {
friend amit;
friend *new;
amit.name = "amit";
amit.age = 16;
amit.gender = 'm';
node_add(new);
new->name = "amit";
printf ("name: %s\n", new->name);
system("PAUSE");
return 0;
}
void node_add(friend* new) {
new = (friend* )malloc(sizeof(friend));
friend* head = new;
new -> next = head;
}
I'm trying now to create a delete node function. I tried to find which node does the user wants to delete, and then delete it by doing
delete -> next = delete -> next -> next
The problem is, I need to get for the first node in the list.
Here is what I wrote:
void node_delete(friend* delete) {
friend *temp;
char name[256];
int i = 0, j = 0;
printf ("Please enter the friend's name you want to delete: \n");
fgets (name, 256, stdin);
fgets (name, 256, stdin);
while (0 == (strcmp(temp -> next -> name, delete -> next -> name))) {
temp = friend -> next;
}
temp -> next = temp -> next -> next;
free (delete);
}
Edit:
It seems my test was a mite too quick, because there is in fact a pretty serious problem with this code, but it's subtle:
In main() you are never actually pointing new at anything. It's just a garbled pointer out into memory space, which might sometimes work, and most of the time, is just terrible.
friend *new; // here's your problem; change this to:
friend *new = malloc(sizeof(friend));
Also, never cast the results of malloc.
Reedit:
How a very simple linked list implementation might look:
typedef struct _node node;
struct _node {
void *payload;
node *next;
};
node *create_node () {
node *retval = malloc(sizeof(node));
retval->payload = NULL;
retval->next = NULL;
return retval;
}
node *add_node (node *target) {
if (target->next)
return;
node *next = create_node();
node->next = next;
}
node *node_search (node *haystack, void *needle) {
while (haystack) {
if (!compare(needle, haystack->payload)) {
return haystack;
} else {
haystack = haystack->next;
}
}
return NULL;
}
Implementation of deletion and insertion are left as an exercise to the reader.
Of course, you alloc memory and assign it to local variable.
If you want to change pointer, pass pointer with one more asterix.
And, by the way, do not name anything like friend or new. Its keywords in C++,
and it create not needed problems.
You should have friend *head global.
And in the
void node_add(friend* new)
{
new = (friend* )malloc(sizeof(friend));
new->next = head;
head = new;
}
You should use a double-pointer.
void node_add(friend **new) {
*new = malloc(sizeof(friend));
/* etc */
}
The issue is in the following line:
amit.name = "amit";
You should be a malloc and doing a strcpy()