I am trying to implement the Linked List data structure for my college course, but on executing the code the following line produces an EXC_BAD_ACCESS(code=1, address=0x8) error.
temp->next = (ptrtonode) malloc(sizeof(struct node));
Following is the code in its entirety.
#include <stdio.h>
#include <stdlib.h>
typedef struct node *ptrtonode;
typedef ptrtonode header;
struct node
{
int data;
ptrtonode next;
};
ptrtonode create(int n)
{
int i;
header temphead = NULL;
ptrtonode temp = temphead;
for(i=0;i<n;i++)
{
temp->next = (ptrtonode) malloc(sizeof(struct node));
printf("Enter data for node %d: ", i+1);
scanf("%d", &temp->next->data);
temp = temp->next;
}
temp->next = NULL;
return temphead;
}
int main(int argc, const char * argv[])
{
header head;
int n;
printf("How many nodes do you wish to create?");
scanf("%d", &n);
head = create(n);
}
Any help would be appreciated.
Thanks all!
On first iteration of the for loop inside the create() function temp is NULL, which is then dereferenced causing the failure (not malloc() causing the failure). You will need to restructure the code slightly to prevent dereferencing a NULL pointer.
Other points:
casting the return value of malloc() is not required.
check the result of scanf() to ensure n was assigned a valid integer (and confirm that the int is positive):
/* scanf() returns the number of assignments made,
which in this case should be 1. */
if (1 == scanf("%d", &n) && n > 0)
{
/* 'n' assigned a sensible value. */
}
Related
This is my algorithm for adding nodes to a linked list which is in a sorted way for surnames of persons.
Here is the code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct Node {
char Name[1024];
char Surname[1024];
char Telno[1024];
struct Node* next;
};
void Add(struct Node** firstnode, struct Node* NewNode)
{
struct Node* tempo;
//printf("%d",strcmp((*firstnode)->Surname,NewNode->Surname));
if (*firstnode == NULL || (strcmp((*firstnode)->Surname,NewNode->Surname) > 0)) {
NewNode->next = *firstnode;
*firstnode = NewNode;
}
else {
tempo = *firstnode;
while (tempo->next != NULL && strcmp(tempo->Surname,NewNode->Surname) < 0) {
tempo = tempo->next;
}
NewNode->next = tempo->next;
tempo->next = NewNode;
}
}
struct Node* CreateNode(char name[1024], char surname[1024], char telno[1024])
{
struct Node* NewNode = (struct Node*)malloc(sizeof(struct Node));
strcpy(NewNode->Name,name);
strcpy(NewNode->Surname,surname);
strcpy(NewNode->Telno,telno);
NewNode->next = NULL;
return NewNode;
}
void Printlinkedlist(struct Node* head)
{
struct Node* temp = head;
while (temp != NULL) {
printf("%s %s %s\n", temp->Name,temp->Surname,temp->Telno);
temp = temp->next;
}
}
struct Node* head = NULL;
struct Node* temp;
int main()
{
int personcount;
char name[1024],surname[1024],telno[1024];
printf("Please give the count of person:");
scanf("%d", &personcount);
for (int i = 0; i < personcount; i++) {
printf("Please give the name of %d. person:", i + 1);
scanf(" %s", &name);
printf("Please give the surname of %d. person:", i + 1);
scanf(" %s", &surname);
printf("Please give the phone number of %d. person:", i + 1);
scanf(" %s", &telno);
temp = CreateNode(name,surname,telno);
Add(&head, temp);
}
printf("\n -------------- Linkedlist --------------\n");
Printlinkedlist(head);
return 0;
}
The first problem is this: For example, if I enter people's surnames as G, A, L, E, K (So first person's last name will be "G", second person's last name will be "A" etc..), it gives an incorrectly ordered output.
And the second one is: If I delete the comment line characters behind the printf inside the add function, I get a segmentation fault that I don't understand why
Thanks for the answer.
It should first be said that you could, and should, have figured it out yourself by either:
Debugging the program:
On Linux: How Can I debug a C program on Linux?
On Windows: How do you debug a C program on Windows?
Enabling core dumps and analyzing the core file you get when your program crashes; see this explanation.
But, more to the point, let's have a look at (some of) your code:
if (*firstnode == NULL || /* another condition */) {
// do stuff
}
else {
// so *firstnode may be NULL here
tempo = *firstnode;
while (tempo->next != /* some value */ && /* another condition*/ ) {
// do stuff
}
// do stuff
}
See the problem? tempo could get assigned a NULL point, and then de-referenced to get to the next field. That would likely cause a segmentation fault.
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.
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);
/* ... */
}
I'm trying to implement a hash table in C, and almost have it. I'm implementing collision resolution via chaining using a linked list in each array slot, and I'd like to be able to chain inside a function call.
Now, the problem is that in order for the modifications to be permanent I believe that I need an additional level of indirection. This is a problem in that when I try to traverse the list the previous element is overwritten by the next (see my comment inside the insert() function). I've tried to pass this array with an additional level of indirection specified a few different ways but I get compiler warnings and seg faults.
This may seem simple to some of you, but it's had me scratching my head for quite some time now, and this scenario (passing array of pointers for modification) is treated nowhere in my text and I can't seem to find this exact question asked (although it may be in a form I don't recognize). I'm not necessarily looking for a 'quick fix' to my code, but I want to understand what is the best practice to accomplish what I'm looking to do.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
//#include "list.c"
struct node{
int key;
struct node* next;
};
void createTable(struct node *table[], int numEls, int numSlots);
int hash(int key, int numSlots);
void insert(struct node *table[], int key, int slot, int numSlots);
void display(struct node *table[], int numEls);
int main(void){
srand(time(NULL));
int numEls, numSlots;
printf("Please enter the desired number of slots in the hash table: ");
scanf("%d", &numSlots);
struct node *table[numSlots];
printf("\nPlease enter the desired number of elements: ");
scanf("%d", &numEls);
printf("\nYour load factor will be %f", (float)numEls/numSlots);
createTable(table, numEls, numSlots);
}
void createTable(struct node *table[], int numEls, int numSlots){
for(int i = 0; i < numSlots; i++)
table[i] = NULL;
for(int j = 0; j < numEls; j++){
for(int k = 0; k < 99999999; k++){}//give the rand function time
int el = rand()%100;
insert(table, el, hash(rand()%100, numSlots), numSlots);
}
display(table, numSlots);
}
int hash(int key, int numSlots){
return((int)(pow(key, 2.819)) % numSlots);
}
void insert(struct node *table[], int key_, int slot, int numSlots){
printf("\nInserting %d into slot %d", key_, slot);
fflush(stdout);
struct node* new = malloc(sizeof(struct node));
(new)->key = key_;
(new)->next = NULL;
struct node** temp = &(table[slot]);
if((*temp) == NULL){
printf(" (*temp) == NULL");
(*temp) = new;
}
else{
printf(" %d", (*temp)->key);
while((*temp)->next != NULL){
printf(" %d", (*temp)->next->key);
(*temp) = (*temp)->next; //head is overwritten with head->next
}
(*temp)->next = new;
printf(" %d", (*temp)->next->key);
}
}
void display(struct node *table[], int numSlots){
for(int i = 0; i < numSlots; i++){
printf("\nSlot %d:", i);
struct node* temp = table[i];
while(temp != NULL){
printf(" %d", temp->key);
temp = temp->next;
}
}
}
In the line with the comment, you are overwriting the pointer to the head (inside the outermost array) with the next element in the linked list, which was probably not your intent.
The correction is to walk down the list of pointers until you found the last pointer, without modifying the main data structure during the walk.
Here is a corrected version of insert().
void insert(struct node *table[], int key_, int slot, int numSlots){
printf("\nInserting %d into slot %d", key_, slot);
fflush(stdout);
struct node* new = malloc(sizeof(struct node));
new->key = key_;
new->next = NULL;
// Here we make a copy of the pointer to the head node in the linked list.
// This way, we never overwrite the original copy which lives in the array itself.
struct node* head = table[slot];
if(head == NULL){
printf(" head == NULL");
table[slot] = new;
}
else{
while(head->next != NULL) {
head = head->next; //head is overwritten with head->next
}
head->next = new;
}
}
This isn't an answer but is too big for a comment... can you explain what this code is meant to be doing?
while((*temp)->next != NULL)
{
printf(" %d", (*temp)->next->key);
(*temp) = (*temp)->next; //head is overwritten with head->next
}
(*temp)->next = new;
I would expect that you want to append the new node at the end of the linked list of existing nodes in this slot. But this code actually updates the head to point to the last node in the list , just like your comment says (leaking memory - the earlier nodes in the list are now unreachable). Then it makes the last node (which is now the only node in the list) point to new.
So your "list" only ever has length 1 or 2, and it leaks memory each time you try to put a third entry in.
It seems to me that there is nothing wrong with your passing of table (which is a list of heads of linked lists) but the problem is that the code that maintains the list for which those are heads, is not right.