Adding node to global linked list causing crash - c

I'm trying to add items to a linked list. The code compiles OK but when I execute the program, it crashes before adding the first node. The code looks OK to me but I must be missing something.
The code uses a global linked list which is necessary for this problem. I think my usage of it may be what is causing the crash.
main.c
#include <stdio.h>
#include <stdlib.h>
#include "LinkedList.h"
int main (int argc, char* argv[])
{
LinkedList *canQueue;
int ii;
createList();
FILE* f;
f = fopen(argv[1], "r");
if(f==NULL)
{
printf("Error: could not open file");
return 0;
}
for(ii = 0; ii < 10; ii++)
{
TinCan* tempCan = malloc(sizeof(TinCan));
fscanf(f, " label_%d", &tempCan->label); /*Read info from file into label field*/
insertLast(canQueue, tempCan); /*Inserts the new can into linked list*/
}
return 0;
}
LinkedList.h
typedef struct TinCan
{
int label;
} TinCan;
typedef struct Node
{
TinCan* data;
struct Node *next;
} Node;
typedef struct LinkedList
{
Node *head;
} LinkedList;
void insertLast(LinkedList* list, TinCan *newData);
void createList();
extern LinkedList* canQueue;
LinkedList.c
#include <stdio.h>
#include <stdlib.h>
#include "LinkedList.h"
LinkedList *canQueue;
void createList() /*creates empty linked list*/
{
canQueue = malloc(sizeof(LinkedList));
canQueue->head = NULL;
}
void insertLast(LinkedList* list, TinCan *newData)
{
Node* newNode = malloc(sizeof(Node));
newNode->data = newData;
newNode->next = NULL;
if(list->head==NULL)
{
list->head=newNode;
}
else
{
Node* temp;
temp = list->head;
while(temp->next!=NULL)
{
temp = temp->next;
}
temp->next = newNode;
}
printf("Added to end");
}

Based on your response, you need to remove this declaration from main:
LinkedList *canQueue;
It is shadowing the global canQueue, which means later on when you call insertLast:
insertLast(canQueue, tempCan);
you are operating on an unintialized pointer.

Related

recursively call in c to create link list

I am new in c so any help will be appreciated. I need to print 10 numbers from a linked list (it doesnt matter which numbers for now) I believe my code will print 9,8,7...0. for example. The linked list will be part of a struct (struct data) that will contain other variables (not important for now)
//linked list
struct listOfNodes {
struct node *root;
};
//list of parameters to send to the function to print nodes
struct data {
struct listOfNodes *list;
int total;
};
I need to send the struct (struct data) as a parameter of a recursive function (addNode). In this recursive function, I need to add a new node to the linked list and call recursively 10 times to create more nodes for the link list, then I need to print the linked list. I have the following code so far
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
//node
struct node {
int value;
struct node *next;
};
//linked list
struct listOfNodes {
struct node *root;
};
//list of parameters to send to the function to print nodes
struct data {
struct listOfNodes *list;
int total;
};
void printNode(struct listOfNodes *list) {
struct node *n = list->root;
while(n!=NULL){
printf("%d\n",n->value);
n=n->next;
}
}
void addNode(void* d){ //parameter needs to be a void*
struct data *o = (struct data *)d ;
if(o->total<10) {
//create new node
struct node *n = malloc(sizeof(struct node));
n->value = o->total;
n->next = NULL;
o->total = o->total + 1;
if(o->list->root == NULL)
{
o->list->root = n;
}
else {
n->next = o->list->root->next;
o->list->root->next = n;
}
addNode(d);
}
}
int main() {
struct data *d= malloc(sizeof(struct data *));
d->total=0;
d->list=NULL;
addNode(d); //add recursively 10 times
if(d->list!=NULL) printNode(d->list);
return 0;
}
But I am getting Segmentation fault (core dumped). Can you please help me?
In your main program, you added list as NULL. But in your addNode, you only check if list->root is NULL. What's happening is when
if(o->list->root == NULL)
{
o->list->root = n;
}
is accessing list->root when list is NULL. You de reference a NULL pointer and segfault.
You probably need
struct listOfNodes *variable=malloc(sizeof(struct listOfNodes));
d->list=variable;
Changes are describe in comments
#include <stdio.h>
// #include <string.h> // <------- 4 not needed.
#include <stdlib.h>
struct node {//node
int value;
struct node *next;
};
struct listOfNodes {//linked list
struct node *root;
};
struct data {//list of parameters to send to the function to print nodes
struct listOfNodes *list;
int total;
};
void printNode(struct listOfNodes *list) {
struct node *n = list->root;
while(n!=NULL){
printf("%d\n",n->value);
n=n->next;
}
}
void addNode(struct data * d){ // <------- 3 no need to be void * so o replaced by d
if(d->total<10) {
//create new node
struct node *n = malloc(sizeof(struct node));
n->value = d->total;
n->next = NULL;
d->total = d->total + 1;
if(d->list->root == NULL)
{
d->list->root = n;
}
else {
n->next = d->list->root->next;
d->list->root->next = n;
}
addNode(d);
}
}
int main() {
struct data *d= malloc(sizeof(struct data)); // <---- 1 allocate data size not pointer size.
d->total=0;
d->list = malloc(sizeof(struct listOfNodes)); // <---- 2 alocate list !
d->list->root = NULL; // <---- 2 init root.
addNode(d); //add recursively 10 times
if(d->list!=NULL) printNode(d->list);
return 0;
}

Phone book Linked list

I have a problem with linked list when I add the contacts to the list and print it out it prints out the first list twice rather than the first and the second list. Please let me know what I am doing wrong.
Thanks.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#define true 1
#define false 0
typedef int boolean;
typedef int Position;
typedef int Count;
typedef struct node_def {
int area_code;
char name[30];
char phone_number[8];
struct mode_def *next;
} Node;
typedef struct {
Position currentPos;
Count nodeCount;
Node *head;
Node *current;
Node *tail;
} ListADT;
void initList(ListADT*);
boolean checkEmpty(ListADT*);
void addList(ListADT*, int, char*, char*);
void printList(ListADT*);
int main(void) {
ListADT phoneList;
initList(&phoneList);
Node *firstNode;
addList(&phoneList, 416, "Sam", "1234567");
addList(&phoneList, 416, "Bob", "7654321");
firstNode-> next;
printList(&phoneList);
printList(&phoneList);
return 0;
}
void initList(ListADT* list){
list->currentPos = -1;
list->nodeCount = 0;
list->head = NULL;
list->tail = NULL;
}
boolean checkEmpty(ListADT* list){
return list->nodeCount == 0 ? true : false;
}
void addList(ListADT* list, int areaCode, char* name, char* phoneNum){
Node* newNode = malloc(sizeof(Node));
assert(newNode);
newNode->area_code = areaCode;
strcpy(newNode->name, name);
strcpy(newNode->phone_number, phoneNum);
newNode->next = NULL;
if(list->nodeCount == 0) {
list->head = newNode;
list->tail = newNode;
list->currentPos = 0;
list->nodeCount = 1;
}
else {
list->tail = newNode;
list->current = list->tail;
list->nodeCount++;
list->currentPos = list->nodeCount -1;
}
}
void printList(ListADT* list){
if(!checkEmpty(list)){
Node* newNode = list->head;
printf("The name is %s\n",newNode->name);
printf("The phone number is %i-%s\n",newNode->area_code,newNode->phone_number);
}else
printf("The list is empty.\n");
}
Mean no harm, but based on your question concerning the current code, I suppose you have to get some more experience in programming, particularly in programming in C++, before writing your own abstract data types.
There are a lot of things done only to the half, and actually you are asking "why does my function, which does nothing else than printing out exactly the first element, print the same element twice if I call this function twice.".
Anyway, some hints:
Typo in struct mode_def *next, should be struct node_def *next.
Make sure that next is actually set somewhere, e.g. else {
list->tail->next = newNode; otherwise you won't get a linked list but unlinked nodes
When printing, traverse the nodes through next, i.e something like while(node!=NULL) { ...; node=node->next; }
firstNode-> next; does simply nothing

How to create head node

I think I got it wrong in newList. Typedef struct implementations must not be change. This is a lab assignment in my school.. Thanks in advance :)
#include<stdio.h>
typedef struct node *nodeptr;
struct node {
int item;
nodeptr next;
};
typedef nodeptr List;
List newList();
newList creates a header and returns a pointer to the header node
void display(List list);
void addFront(List list, int item);
List newList(){
List list;
list=(nodeptr)malloc(sizeof(List));
list->next=NULL;
return list;
} //I think my new list is incorrect..
void display(List list){
nodeptr ptr=list;
while(ptr!=NULL){
printf("%d",ptr->item);
ptr=ptr->next;
}
printf("\n");
}
void addEnd(List list, int item){
nodeptr temp, ptr;
temp=(List)malloc(sizeof(nodeptr));
temp->item=item;
temp->next=NULL;
if(list->next==NULL)
list=temp;
else{
ptr=list;
while(ptr->next!=NULL)
ptr=ptr->next;
ptr->next=temp;
}
}
I can't seem to add 10 from the list..
int main(void){
List list=newList();
addEnd(list,10);
display(list);
}
There are many ways you can go about this depending on what you actually want (because just creating a node doesn't make a lot of sense by itself). But generally you have three common options — create it on the stack, create that node in the global memory, or allocate it dynamically. Below are some examples.
On stack
#include <stdlib.h>
struct node {
int item;
struct node *next;
};
int main()
{
struct node head;
head.item = 0;
head.next = NULL;
/* Do something with the list now. */
return EXIT_SUCCESS;
}
In Global Memory
#include <stdlib.h>
struct node {
int item;
struct node *next;
};
static struct node head;
int main()
{
/* Do something with the list now. */
return EXIT_SUCCESS;
}
Dynamic Allocation
#include <stdlib.h>
#include <stdio.h>
struct node {
int item;
struct node *next;
};
int main()
{
struct node *head;
head = calloc(1, sizeof(struct node));
if (head == NULL) {
perror("calloc");
return EXIT_FAILURE;
}
/* Do something with the list now. */
return EXIT_SUCCESS;
}
You can read up on any of the above example in any introductory C book.
Hope it helps. Good Luck!

assignment from incompatible pointer type in linked list (C)

I am having some problems creating a linked list and also some helper functions that I am trying to make. My code is as follows:
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include "getNextWord.h"
#define MAX_WORD_SIZE 256
typedef struct{
int counter;
char* key;
struct node* next;
} node;
node* createNode(char* words){
node* head;
if(!(head=malloc(sizeof(node)))) return NULL;
head->key=words;
head->next=NULL;
return head;
}
node* addToList(node* head, char* words){
node* newNode;
newNode=createNode(words);
newNode->next = head;
return newNode;
}
int find(node* head){
if (head->next != NULL){
node* next = head->next;
while(head != NULL){
if (strcmp(head->key,next->key)==0){
head->counter++;
head=head->next;
return 1;
}
else{
head=head->next;
}
}
}
return 0;
}
void printList(node* head){
node* pointer = head;
while (pointer != NULL){
printf("%s",pointer->key);
pointer=pointer->next;
}
printf("\n");
}
int main(int argc, char* argv[]){
if(argc<2){
fprintf(stderr, "Not enough arguments given\n");
}
for(int i=1; i< argc; i++){
FILE* fd=fopen(argv[i], "r");
if(fd != NULL){
char* words;
node* head = NULL;
while((words=getNextWord(fd)) != NULL){
find(head);
if (find(head) == 0){
createNode(words);
}
printList(head);
fprintf(stdout,"%s\n",words);
}
}
else(printf("No such file exists"));
fclose(fd);
}
return 0;
}
I looked around on the Internet and it would seem I am following what most people are doing in regards to the linked list. I wasn't getting any errors before, just a bunch of "warning: assignment from incompatible pointer type" in the following functions:
addtolist (the line before the return)
find (before return one and the else line)
printlist (the last line in the while loop)
I know it's not that great of code, I'm not the best programmer, but just trying to learn. Also, my getnextword does work, but if it's needed for something I can post that too.
Your are mixing up two different "namespaces" the "tag" namespace for struct and alike and the identifier namespace for typedef. The easiest to get along with this is to forward declare the types you are going to use:
typedef struct node node;
Then afterwards you can use node or struct node interchangeably. Even inside
struct node {
// something
node * next;
};
typedef struct tag_node {
int counter;
char* key;
struct tag_node* next;
} node;
for starters.
As a side-note, I can't imagine how you free() words within main (careful, it might leak).
edit - I accidentally some styles
Try this:
struct node {
int counter;
char* key;
struct node* next;
};
You may need to replace node with struct node in other places in the code.
multiple issues:
int find(node* node){
node* next = node->next; // what if next is NULL ?
while(node != NULL){
if (strcmp(node->key,next->key)==0){ // if next is NULL this will crash
node->counter++;
return 1;
node=node->next; // never reached since return 1 above.
}
else{
node=node->next;
}
}
return 0;
}
....
probably good to rename createlist to createnode since that seems to be the function.
node* createList(char* words){
node* node;
if(!(node=malloc(sizeof(node)))) return NULL;
node->key=words;
node->next=NULL;
return node;
}
the string that comes in 'words' is never stored, you need to create a copy of the words and store it e.g.:
node->key = strdup(words);

Pointer that points to return of function. Initialization from incompatible pointer type

I have some trouble with pointers. I have a function that should return the node in a linked list, the function should return the pointer to a variable. I'm confused and cannot see what I do wrong!
data.h - header file
int add(int num);
struct message *findMessage(int num);
typedef struct list_el message;
data.c - Linked list.
#include <stdio.h>
#include <stdlib.h>
struct list_el {
int num;
struct list_el *next;
};
typedef struct list_el message;
struct list_el *head, *tail;
int addNode(struct list_el *curr)
{
if(head == NULL) {
head = curr;
} else {
tail->next = curr;
}
curr->next = NULL;
return 0;
}
int add(int num)
{
message *curr;
head = NULL;
curr = (message*) malloc(sizeof(message));
curr->num = num;
addNode(curr);
return 0;
}
message *findMessage(int num)
{
message *curr;
for(curr = head; curr != NULL; curr = curr->next) {
if(curr->num == num) {
return curr;
}
}
return NULL;
}
Main.c - MAIN
#include <stdio.h>
#include "data.h"
int main(void)
{
int num = 2;
add(num);
message *curr = findMessage(num);
return 0;
}
Why not include the definition of struct list_el into the header? Otherwise main cannot work with it.

Resources