Error in using Linked List in C program [closed] - c

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 9 years ago.
I am working on an extra credit project for class and here are the specs:
You will write a c program (you should use a design tool but I do not want to see it)
The program will use dynamic memory to create a linked list (NO ARRAYS PERMITTED)
The program will store unlimited number of student records (limited only by RAM).
A student record will consist of Student Name, and Age…you may need to add two additional fields to make this work.
The program will have a way for the user to added records.
The program will have a way for the user to display ALL records (to the screen only, no sort needed).
The program needs a way to quit.
I have all the code finished, but I am getting this pesky error. This is exactly what I see on my computer:
1>linkedProject.obj : error LNK2019: unresolved external symbol _add referenced in function _main
1>E:\Spring 2013\C Programing Class\linkedProject\Debug\linkedProject.exe : fatal error LNK1120: 1 unresolved externals
And here is my code:
#include<stdlib.h>
#include<stdio.h>
#include<malloc.h>
#include<conio.h>
#include<string.h>
#include<ctype.h>
#define pause system ("pause")
// prototype variables
struct node * initnode(char*, int);
void printnode(struct node*);
void printflist(struct node*);
void add(struct node*);
struct node* searchname(struct node*, char*);
struct node{
char name[20];
int age;
struct node *next;
};
struct node *head = (struct node*) NULL;
struct node *end = (struct node*) NULL;
struct node* initnode(char *name, int age){
struct node *ptr;
ptr = (struct node*) calloc(1, sizeof(struct node));
if(ptr == NULL)
return (struct node*) NULL;
else {
strcpy(ptr->name, name);
ptr->age = age;
return ptr;
}
}
void printnode(struct node *ptr) {
printf("Name -> %s\n", ptr->name);
printf("Age -> %d\n", ptr->age);
}
void printlist (struct node *ptr) {
while (ptr != NULL) {
printnode(ptr);
ptr = ptr->next;
}
}
main() {
char name[20];
int age, choice = 1;
struct node *ptr;
while(choice != 3){
system("cls");
printf("1. Add a name\n");
printf("2. List all names\n");
printf("3. Exit");
printf("\nEnter Menu Selection: ");
scanf("%d", &choice);
switch(choice) {
case 1: printf("\nEnter a name: ");
scanf("%s", &name);
printf("Enter age: ");
scanf("%d", &age);
ptr = initnode(name, age);
add (ptr);
break;
case 2: printlist(head);
break;
case 3: exit(3);
default: printf("Invalid Entry");
}// end of switch
}// end of while
}// end of main
All help is greatly appreciated!!

The linker is telling you that it can't find the add function.
You have declared:
void add(struct node*)
in your prototypes, but you haven't defined it anywhere.

You declare add method in prototype. and add(ptr) call in main method. But I cann't see add method definiton. That's why, Compiler rise linker error.

Related

Upon creation of 3 - 5 nodes, segmentation fault is encountered. Why? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed last year.
Improve this question
I am currently trying to create a phonebook with a linked list. I am focusing first on the insertion function but the problem is that once I create 3 - 5 nodes, onlineGDB shows the error "malloc : corrupted top size", and VS Code shows that I got a segmentation error.
I assume this is an error with the way I am allocating memory. This is the first time that I am working on a structure that contains strings as data instead of integer so I might have missed a thing or two.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node{
char name[30];
char number[15];
struct node *next;
};
void showMenu();
void insertData(struct node **head, char person[], char phone[]);
void showData(struct node *head);
int main(){
struct node *head = NULL;
char name[30], number[15];
while(1)
{
printf("Name : ");
scanf(" %[^\n]s", name);
printf("Number: ");
scanf(" %[^\n]s", number);
insertData(&head, name, number);
showData(head);
}
return 0;
}
void insertData(struct node **head, char person[], char phone[]){
struct node *new_node = (struct node*) malloc(sizeof(struct node*));
strcpy(new_node->name, person);
strcpy(new_node->number, phone);
new_node->next = *head;
*head = new_node;
}
void showData(struct node *head){
while(head != NULL)
{
printf("%s\t\t%s\n", head->name, head-> number);
head = head->next;
}
printf("\n");
}
Use malloc(sizeof(struct node)) instead of malloc(sizeof(struct node*)) in your function insertData(). You want to allocate the size of the node and not the pointer to node.

How to fix the problem of file.exe stop running after one insertion in linked list

#include<stdio.h>
#include<stdlib.h>
struct node{
int id;
char name[50];
float point;
char grade;
struct node *next;
};
struct node *head;
void DataEntry(struct node *);
void GetData(struct node *);
void DataDisp();
void Insert()
{
struct node *p;
p=(struct node*)malloc(sizeof(struct node));
DataEntry(p);
if(head==NULL)
{
head=p;
}
else
{
struct node *q;
q=head;
while(q!=NULL)
{
q=q->next;
}
q->next=p;
p->next=NULL;
}
}
void DataEntry(struct node *p)
{
printf("Enter value of Id employee\n");
scanf("%d",&p->id);
printf("Enter name of the person\n");
scanf("%s",p->name);
printf("Enter points got by Employee\n");
scanf("%f",&p->point);
printf("Enter grade of the person\n");
fflush(stdin);
scanf("%c",&p->grade);
}
void GetData(struct node *q)
{
printf("The data entered by you is as follows\n");
printf("Id is %d\n",q->id);
printf("Name is %s\n",q->name);
printf("Point is %f\n",q->point);
printf("Grade is %c\n",q->grade);
}
void DataDisp()
{
struct node *z;
z=head;
if(z==NULL)
{
printf("List is Empty\n");
return;
}
while(z!=NULL)
{
GetData(z);
z=z->next;
}
}
int main()
{
Insert();
DataDisp();
}
I have implemented a singly linked list, I insert data in a list using Insert() function and displaying the data using DataDisp() function in DataDisp() function I have used GetData() function which is accessing data from linked list nodes. The problem here is I can do the first insertion and it displays data also using DataDisp() but after that, there is error file.exe stop running. I think there is a segmentation fault; I tried my best to solve the problem but could not run it successfully. Please help.
ONE MORE THING IS TRY TO PREVENT USE OF "FFLUSH" KEYWORD.THIS IS NOT A PORTABLE WAY OF CLEANING THE INPUT BUFFER, AND MAY NOT WORK WITH ALL COMPILER.

Unable to Access Casted Void Pointer

I am creating a linked list that contains nodes with the "dataItem" of a void pointer. The purpose of this is in order to be able for the Node to contain any kind of data. However, I am unable to access the void pointer's data, even when that data is casted to the correct type.
My code looks like the following:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Student
{
char stuName[51];
char stuMajor[5];
double GPA;
char stuID[10];
}student;
typedef struct Node
{
union{
void *dataPtr;
int countr;
}dataItem;
int link;
struct Node* next;
}node;
void readData(struct Node *);
void main(){
node head;
node temp;
readData(&temp);
student *ptr = (student *)(temp.dataItem.dataPtr);
printf("%s %d", ptr->stuName, ptr->GPA);//breaks here because unable to access memory
}
void readData(struct Node *link)
{
link = (node *)malloc(sizeof(node));
student *ptr = (student *)malloc(sizeof(struct Student));
printf("enter the student name : ");
fflush(stdin);
scanf("%[^\n]", ptr->stuName);
printf("enter the student's major : ");
fflush(stdin);
scanf("%[^\n]", ptr->stuMajor);
printf("enter the student GPA : ");
scanf("%lf", &(ptr->GPA));
printf("enter the student ID : ");
fflush(stdin);
scanf("%[^\n]", ptr->stuID);
link->dataItem.dataPtr = ptr;
}
I know I definitely have a pointer wrong somewhere I'm not unsure how. I also have the node within my readData function point to a new malloc of Node because I want a new node each time readData is called for when I implement the linked list further.
Your code is very broken,
You didn't include any header file, you need at least stdlib.h for malloc(), and stdio.h for printf() and scanf().
Your main() definition is wrong, because main() must return int.
You fflush(stdin) which is undefined behavior.
You ignore the return value from scanf().
You assume that malloc() always returns a valid pointer.
You called readData() which is not declared yet.
But the most important mistake, is that you passed node temp's address to readData() and you malloc()ed it, but you didn't return a pointer to it, thereby losing all the changes made inside readData() which will not work anyway because it's undeclared at the moment you called it.
I fixed your code, because I know that you didn't like my answer, but check out the fixes which are related to the answer, and now it works as I expected
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Student
{
char stuName[51];
char stuMajor[5];
double GPA;
char stuID[10];
} student;
typedef struct Node
{
union{
void *dataPtr;
int countr;
} dataItem;
int link;
struct Node* next;
} node;
void readData(struct Node **link);
int main()
{
node *head;
student *ptr;
readData(&head);
ptr = head->dataItem.dataPtr;
if (ptr != NULL)
printf("%s\t%g", ptr->stuName, ptr->GPA);
return 0;
}
void readData(struct Node **link)
{
student *ptr;
if (link == NULL)
return;
*link = malloc(sizeof(node));
if (*link == NULL)
return;
memset(*link, 0, sizeof(node));
ptr = malloc(sizeof(struct Student));
if (ptr == NULL)
return;
printf("enter the student name : ");
if (scanf("%50[^\n]%*c", ptr->stuName) != 1)
ptr->stuName[0] = '\0';
printf("enter the student's major : ");
if (scanf("%4[^\n]%*c", ptr->stuMajor) != 1)
ptr->stuMajor[0] = '\0';
printf("enter the student GPA : ");
if (scanf("%lf%*c", &(ptr->GPA)) != 1)
ptr->GPA = 0;
printf("enter the student ID : ");
if (scanf("%9[^\n]%*c", ptr->stuID) != 1)
ptr->stuID[0] = 0;
(*link)->dataItem.dataPtr = ptr;
}
I also added some safety fixes to scanf() adding the length modifier to prevent buffer overflow, and also remove the trailing '\n' with "%*c" specifier, it will not work if multiple spaces follow the value, but you can test it meanwhile just pressing Enter/Return, if you want more sofisticated input, you should use something else instead of scanf().
This:
void readData(struct Node *link)
{
link = (node *)malloc(sizeof(node));
You throw away the link parameter value that was passed in, instead assigning it a new allocation via malloc. This is your most significant problem, I think. A simple fix would be to delete the line performing the malloc.
You want to pass a pointer to a pointer (or address of a pointer) to a node to the readData() function. readData allocates a new node and fills it; what happens in your code is that readData() gets a copy of the address of temp, overwrites the copy of this address with a new address, the one obtained from malloc (which is invisible to the calling code in main()) and then fills that malloc'ed object. Upon return from readData the malloc'ed object is inaccessible.
What you wanted to do is this:
void main(){
node head;
node *tempAddr; // pointer
readData(&tempAddr); // pass address of that pointer
and then use *tempAddr in main instead of temp.
void readData(struct Node **linkAddr)
{
node *link = *linkAddr = (node *)malloc(sizeof(node));
[...]
unwind would complain that you should not cast the result of malloc, but I think it's fine. I also do not care about the return value of main, or its arguments.

Issue with linked list in c

I was trying out linked lists and for some reason it isnt doing what it is supposed to do. When I enter the quantity after choosing 1 it is all good until the node is add to the existing list, after which the quantity becomes a weird string of numbers. And also when ever i try adding more than one node to the donate list the program crashes.
EDIT: The above problem is solved but there is another problem which I forgot to mention
It is when I am trying to print the list out, nothing gets printed. This happens when I choose 4.
EDIT2: The print function is only printing out the first node nothing after that.
Please help.
Here's the code.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct donation{
char name[50];
int quant;
struct donation* next;
}donate;
donate* addItem(donate *mylist,donate *temp){
donate *front=(donate*)malloc(sizeof(donate*));
if(mylist==NULL)
return temp;
front=mylist;
while(mylist->next!=NULL)
mylist=mylist->next;
mylist->next=temp;
return front;
}
void print(donate* donList){
printf("Printing the Donations Table\n\n");
if(donList!=NULL){
while(donList->next!=NULL){
printf("%s %d\n",donList->name,donList->quant);
donList=donList->next;
}
}
}
main(){
donate *list=NULL;
while(1){
int choice;
printf("1. Add a donation\n);
printf("Enter your choice: ");
scanf("%d",&choice);
if(choice==1){
donate* temp=(donate*)malloc(sizeof(donate*));
printf("\nEnter inventory type: ");
scanf("%s",temp->name);
printf("Enter the amount: ");
scanf("%d",&temp->quant);
temp->next=NULL;
list=addItem(list,temp);
printf("\nDonation Added!\n");
printf("%s %d\n",list->name,list->quant);
}
else if(choice==4){
print(list);
}
}
system("pause");
return 0;
}
Thanks!
One problem is that you are mallocing space for a donate pointer. You need to allocate space for the struct itself.
donate* temp=(donate*)malloc(sizeof(donate*));
should be
donate* temp= malloc(sizeof(donate));
Since you are doing a malloc, prior to adding an item, I think addItem just needs to be:
donate* addItem(donate *mylist,donate *temp)
{
if (mylist != NULL)
temp->next = mylist;
return temp;
}
It looks like you would not print a 1 item list:
printf("Printing the Donations Table\n\n");
if(donList!=NULL){
printf("Not NULL!!!!\n");
while(donList->next!=NULL){
printf("%s %d\n",donList->name,donList->quant);
donList=donList->next;
}
}
I think it should be:
printf("Printing the Donations Table\n\n");
if (donList!=NULL)
{
printf("Not NULL!!!!\n");
do
{
printf("%s %d\n",donList->name,donList->quant)
donList=donList->next;
}
while(donList != NULL);
}
Try running your program linked to efence or with valgrind.
Both will tell you when and where things start to go bad.
There are two issue that I see. First is the issue pointed out by Scooter. Second is you have a memory leak in the first line of addItem().
Edit To answer your second question, you will need to fix the build error; you reference reqList in main() but never declare it.
Here is a corrected version of the code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
typedef struct donation{
char name[50];
int quant;
struct donation* next;
}donate;
donate* addItem(donate *mylist,donate *temp){
if(mylist==NULL)
return temp;
donate *front=mylist;
while(mylist->next!=NULL)
mylist=mylist->next;
mylist->next=temp;
return front;
}
main(){
donate *list=NULL;
while(1){
int choice;
printf("1. Add a donation\n);
printf("Enter your choice: ");
scanf("%d",&choice);
if(choice==1){
donate* temp=(donate*)malloc(sizeof(donate));
printf("\nEnter inventory type: ");
scanf("%s",temp->name);
printf("Enter the amount: ");
scanf("%d",&temp->quant);
temp->next=NULL;
list=addItem(list,temp);
printf("\nDonation Added!\n");
printf("%s %d\n",list->name,list->quant);
}
}
system("pause");
return 0;
}
just make correction here
donate *front=(donate*)malloc(sizeof(donate*))
to
donate *front=(donate*)malloc(sizeof(donate))

segmentation fault while implementing the binary tree in C [closed]

This question is unlikely to help any future visitors; it is only relevant to a small geographic area, a specific moment in time, or an extraordinarily narrow situation that is not generally applicable to the worldwide audience of the internet. For help making this question more broadly applicable, visit the help center.
Closed 11 years ago.
I got a segmentation fault in the code when I am implementing the binary tree and couldn't figure out why.
#include <stdio.h>
#include <stdlib.h>
struct tree{
int info;
struct tree *lptr,*rptr;
};
typedef struct tree node;
node *create(int, node *);
node *insert(node *);
void preorder(node *);
void inorder(node *);
void postorder(node *);
int main(){
node *root=NULL;
int n,choice=0;
while(choice!=6){
printf("\n\n\t\tMENU");
printf("\n\t1:CREATE\n\t2:INSERTION\n\t3:POSTORDER");
printf("\n\t4:INORDER\n\t5:PREORDER\n\t6:EXIT");
printf("\n\n\tEnter your choice:\t");
scanf("%d",&choice);
switch(choice){
case 1:
printf("\n\tHow many elements to enter\t");
scanf("%d",&n);
root=NULL;
root=create(n,root);
return 0;
}
node *create(int n, node *root){
int i;
for(i=0;i<n;i++)
insert(root);
return root;
}
node *insert(node *root){
int val;
node *temp, *p, *parent;
p=malloc(sizeof(node));
printf("\nEnter data for the node: ");
scanf("%d",&val);
p->info=val;
p->lptr=NULL;
p->rptr=NULL;
if(root=NULL)
root=p;
else{
temp=root;
while(temp){
parent=temp;
if(val<temp->info)
temp=temp->lptr;
if(val>temp->info)
temp=temp->rptr;
if(val==temp->info){
printf("Duplicate data!\n");
free(p);
break;
}
}
if(!temp&&p){
if(val<parent->info) //SEGMENTATION FAULT HERE!!!
parent->lptr=p;
if(val>parent->info)
parent->rptr=p;
}
}
return root;
}
void preorder(node *root){
if(root==NULL)
printf("\n\tEMPTY TREE!\n");
else{
printf("%5d",root->info);
if(root->lptr)
preorder(root->lptr);
if(root->rptr)
preorder(root->rptr);
}
}
void inorder(node *root){
if(root==NULL)
printf("\n\tEMPTY TREE!\n");
else{
if(root->lptr)
inorder(root->lptr);
printf("%5d",root->info);
if(root->rptr)
inorder(root->rptr);
}
}
void postorder(node *root){
if(root==NULL)
printf("\n\tEMPTY TREE!\n");
else{
if(root->lptr)
inorder(root->lptr);
if(root->rptr)
inorder(root->rptr);
printf("%5d",root->info);
}
}
Your problem is on these lines about 10 lines into your insert function:
if(root=NULL)
root=p;
You are assigning root to NULL instead of comparing it to NULL. Then, since NULL evaluates to false, root does not get assigned p. In fact those two lines guarantee that root is NULL after they execute. You just need to add an = to make it a comparison like:
if(root == NULL)
root = p;
This is just an aside, but I recommend putting spaces around your comparison operators. It would make this error much more noticeable, and would make lines like: val>parent->info much more readable, as that line could easily be mistaken for val->parent->info
Edit
As Mark pointed out in the comment below, since == is commutative, but = isn't, you can also avoid this error by switching the order of the operands when you have a value on one side. If you put it on the left like (0 == root) or (NULL == root). The compiler will catch the error for you if you leave an = out since (0 = root) is not syntactically correct.

Resources