Pointer problem while using Linked list in C - c

I'm working on a c programming code and most of the code is working fine except the polynomial Multiplication part. It has a runtime error. please help me in removing this runtime error from Polynomial Multiplication, I couldn't find the error i think it's in the third for loop.
Thanks...
It will be great if you solve the error
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
#define MAX 17
typedef struct node
{
int coeff;
struct node *next;
}node;
node * init();
void read(node *h1);
void print(node *h1);
node * add(node *h1,node *h2);
node * multiply(node *h1, node *h2);
void main()
{
node *h1=NULL,*h2=NULL,*h3=NULL;
int option;
do
{
printf("\n1 : create 1’st polynomial");
printf("\n2 : create 2’nd polynomial");
printf("\n3 : Add polynomials");
printf("\n4 : Multiply polynomials");
printf("\n5 : Quit");
printf("\nEnter your choice :");
scanf("%d",&option);
switch(option)
{
case 1:
h1=init();
read(h1);
break;
case 2:
h2=init();
read(h2);
break;
case 3:
h3=add(h1,h2);
printf("\n1’st polynomial -> ");
print(h1);
printf("\n2’nd polynomial -> ");
print(h2);
printf("\n Sum = ");
print(h3);
break;
case 4:
h3=multiply(h1,h2);
printf("\n1’st polynomial -> ");
print(h1);
printf("\n2’nd polynomial -> ");
print(h2);
printf("\n Product = ");
print(h3);
break;
}
}while(option!=5);
}
void read(node *h)
{
int n,i,j,power,coeff;
node *p;
p=init();
printf("\n Enter number of terms :");
scanf("%d",&n);
/* read n terms */
for (i=0;i<n;i++)
{
printf("\nenter a term(power coeff.)");
scanf("%d%d",&power,&coeff);
for(p=h,j=0;j<power;j++)
p=p->next;
p->coeff=coeff;
}
}
void print(node *p)
{
int i;
for(i=0;p!=NULL;i++,p=p->next)
if(p->coeff!=0)
printf("%dX^%d ",p->coeff,i);
}
node * add(node *h1, node *h2)
{
node *h3,*p;
h3=init();
p=h3;
while(h1!=NULL)
{
h3->coeff=h1->coeff+h2->coeff;
h1=h1->next;
h2=h2->next;
h3=h3->next;
}
return(p);
}
node * multiply(node *h1, node *h2)
{
node *h3,*p,*q,*r;
int i,j,k,coeff,power;
h3=init();
for(p=h1,i=0;p!=NULL;p=p->next,i++)
for(q=h2,j=0;q!=NULL;q=q->next,j++)
{
coeff=p->coeff * q->coeff;
power=i+j;
for(r=h3,k=0;k<power;k++)
r=r->next;
r->coeff=r->coeff+coeff;
}
return(h3);
}
node * init()
{
int i;
node *h=NULL,*p;
for(i=0;i<MAX;i++)
{
p=(node*)malloc(sizeof(node));
p->next=h;
p->coeff=0;
h=p;
}
return(h);
}

There is at least a probleme here in the multiply function:
...
for (r = h3, k = 0; k < power; k++)
r = r->next;
r->coeff = r->coeff + coeff;
...
At some point r becomes NULL and at the next step when you dereference r with r->coeff (r being NULLnow) your program will result un undefined behaviour (a segfault on most platforms).

There were several problems:
Memory was leaked: make sure you can point out a free for every malloc.
read was creating a new list, but leaking it and never updating the data in h1 or h2.
add didn't check for NULL h2.
The result of addition/multiplication was unnecessarily retained.
There was an arbitrary maximum of 17 nodes - the whole point of a linked list is so that there's no need to maintain such arbitrary limits.
Variables had scopes that were too large. This is 2011: one can declare variables near to point of use and not at the beginning of the block.
The use of scanf was non-idiomatic and inapplicable to interactive line-oriented input. For such input, read complete lines and parse them, not the stdin stream. In the stdin stream, a newline is a field separator and you don't want that, I think.
There weren't any asserts: program defensively, assert what you think should be true.
This works and should be correct and free of undefined behavior under all conditions.
// https://github.com/KubaO/stackoverflown/tree/master/questions/c-linked-debug-52867729
#include <assert.h>
#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node {
int power; // primary key for sorting
int coeff;
struct Node *next;
} Node;
Node *new_node(Node *prev, Node *next, int power);
Node *get_node(Node **head, Node *hint, int power);
void delete_nodes(Node *head);
Node *read(void);
void print(const Node *head);
Node *add(const Node *head1, const Node *head2);
Node *multiply(const Node *head1, const Node *head2);
void print_nodes(const Node *n1, const Node *n2, const char *extra_label,
const Node *extra);
const char *arity_suffix(int n);
bool parse_line(int max_length, const char *fmt, int count, ...);
static void *guarded_malloc(size_t size) {
void *result = malloc(size);
if (!result) {
fprintf(stdout, "Memory allocation has failed: exiting.");
abort();
}
return result;
}
int main() {
Node *h1 = NULL, *h2 = NULL;
int option;
do {
printf("\n1 : Create 1'st polynomial");
printf("\n2 : Create 2'nd polynomial");
printf("\n3 : Print polynomials");
printf("\n4 : Add polynomials");
printf("\n5 : Multiply polynomials");
printf("\n6 : Quit");
printf("\nEnter your choice: ");
if (!parse_line(10, "%d", 1, &option)) continue;
switch (option) {
case 1:
delete_nodes(h1);
h1 = read();
break;
case 2:
delete_nodes(h2);
h2 = read();
break;
case 3:
print_nodes(h1, h2, NULL, NULL);
break;
case 4: {
Node *sum = add(h1, h2);
print_nodes(h1, h2, "Sum", sum);
delete_nodes(sum);
break;
}
case 5: {
Node *prod = multiply(h1, h2);
print_nodes(h1, h2, "Product", prod);
delete_nodes(prod);
break;
}
}
} while (option != 6);
delete_nodes(h1);
delete_nodes(h2);
}
Node *read() {
int n;
printf("\n Enter number of terms: ");
if (!parse_line(10, "%d", 1, &n)) return NULL;
/* read n terms */
Node *head = NULL;
for (int i = 0; i < n;) {
int power, coeff;
printf("\nEnter the %d%s term (power coeff): ", i + 1, arity_suffix(i + 1));
if (!parse_line(80, "%d%d", 2, &power, &coeff) || !coeff) continue;
Node *p = get_node(&head, NULL, power);
if (!p->coeff) i++; // count only new terms
p->coeff = coeff;
}
return head;
}
void print(const Node *p) {
for (; p; p = p->next) printf("%dX^%d ", p->coeff, p->power);
}
void add_to(Node **sum, const Node *h) {
Node *r = NULL;
for (; h; h = h->next) {
r = get_node(sum, r, h->power);
r->coeff += h->coeff;
}
}
Node *add(const Node *h1, const Node *h2) {
Node *sum = NULL;
add_to(&sum, h1);
add_to(&sum, h2);
return sum;
}
Node *multiply(const Node *h1, const Node *h2) {
Node *prod = NULL;
for (const Node *p = h1; p; p = p->next) {
Node *r = NULL;
for (const Node *q = h2; q; q = q->next) {
int power = p->power + q->power;
r = get_node(&prod, r, power);
r->coeff += p->coeff * q->coeff;
}
}
return prod;
}
Node *new_node(Node *prev, Node *next, int power) {
assert(!prev || prev->power < power);
assert(!next || next->power > power);
Node *node = guarded_malloc(sizeof(Node));
node->power = power;
node->coeff = 0;
node->next = next;
if (prev) prev->next = node;
return node;
}
void delete_nodes(Node *head) {
while (head) {
Node *p = head;
head = head->next;
free(p);
}
}
static bool list_contains(Node *head, Node *elt) {
for (; head; head = head->next)
if (head == elt) return true;
return false;
}
Node *get_node(Node **head, Node *hint, int power) {
Node *node = hint;
Node *next = hint ? hint->next : head ? *head : NULL;
assert(!hint || !*head || list_contains(*head, hint));
assert(!hint || hint->power <= power);
assert(!node || !next || node->power < next->power);
while (next && next->power <= power) {
node = next;
next = next->next;
}
if (!node || node->power != power) {
assert(!node || node->power < power);
Node *n = new_node(node, next, power);
if (!node) *head = n;
node = n;
}
return node;
}
void print_nodes(const Node *h1, const Node *h2, const char *extra_label,
const Node *extra) {
printf("\n1'st polynomial -> ");
print(h1);
printf("\n2'nd polynomial -> ");
print(h2);
if (extra_label) {
printf("\n %s = ", extra_label);
print(extra);
}
printf("\n");
}
const char *arity_suffix(int n) {
if (n == 0) return "st";
if (n == 1) return "nd";
return "rd";
}
bool parse_line(int max_length, const char *fmt, int count, ...) {
bool result = false;
int const buf_size = max_length + 2; // include \n and zero termination
char *const buf = guarded_malloc((size_t)buf_size);
char *const str = fgets(buf, buf_size, stdin);
if (str) {
size_t n = strlen(str);
if (str[n - 1] == '\n') { // we must have read a whole line
str[n - 1] = '\0'; // remove the newline
va_list ap;
va_start(ap, count);
int rc = vsscanf(buf, fmt, ap);
va_end(ap);
result = rc == count;
}
}
free(buf);
return result;
}

I think you should use memcopy in read method
void read(node *h)
{
int n,i,j,power,coeff;
node *p;
p=init();
printf("\n Enter number of terms :");
scanf("%d",&n);
/* read n terms */
for (i=0;i<n;i++)
{
printf("\nenter a term(power coeff.)");
scanf("%d%d",&power,&coeff);
for(p=h,j=0;j<power;j++)
p=p->next;
p->coeff=coeff;
}
memcpy (h, p, sizeof(node))
}

Related

heap sort using binary tree

I was trying to figure out a code about heap sort using binary tree that I saw on stackoverflow.com,
here is the code:
//Heap Sort using Linked List
//This is the raw one
//This getRoot function will replace the root with number in the last node, after the main prints the largest number in the heap
//The heapSort function will reconstruct the heap
//addNode function is as same as in binary search tree
//Note addNode and heapSort are recursive functions
//You may wonder about the for loop used in main, this actually tells the depth of the tree (i.e log base2 N)
//With this value these functions find where to trverse whether left or right(direction), with help of macro GETBIT (0-left,1-right)
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#define GETBIT(num,pos) (num >> pos & 1)
struct node
{
int data;
struct node *left;
struct node *right;
};
typedef struct node node;
int nodes;
node *first, *tmp, *current;
void addNode(node *,node *,int);
void swap(int *, int *);
void getRoot(node *, int);
void heapSort(node *);
int main()
{
int num;
int cont,i,j;
while(1) //It gets number from user if previous value is non zero number
{
printf("Enter a number\n");
scanf("%d",&num);
if(!num) //i'm using 0 as terminating condition to stop adding nodes
break; //edit this as you wish
current = (node *)malloc(sizeof(node));
if(current == 0)
return 0;
current->data = num;
nodes++;
for(i=nodes,j=-1; i; i >>= 1,j++);
if(first == 0)
{
first = current;
first->left = 0;
first->right = 0;
}
else
addNode(first,first,j-1);
printf("Need to add more\n");
}
printf("Number of nodes added : %d\n",nodes);
while(nodes)
{
printf(" %d -> ",first->data); //prints the largest number in the heap
for(i=nodes,j=-1; i; i >>= 1,j++); //Updating the height of the tree
getRoot(first,j-1);
nodes--;
heapSort(first);
}
printf("\n\n");
return 0;
}
void swap(int *a,int *b)
{
*a = *a + *b;
*b = *a - *b;
*a = *a - *b;
}
void addNode(node *tmp1,node *parent, int pos)
{
int dirxn = GETBIT(nodes,pos); // 0 - go left, 1 - go right
if(!pos)
{
if(dirxn)
tmp1->right = current;
else
tmp1->left = current;
current->left = 0;
current->right = 0;
if(current->data > tmp1->data)
swap(&current->data, &tmp1->data);
}
else
if(dirxn)
addNode(tmp1->right,tmp1,pos-1);
else
addNode(tmp1->left,tmp1,pos-1);
if(tmp1->data > parent->data)
swap(&parent->data,&tmp1->data);
}
void getRoot(node *tmp,int pos)
{
int dirxn;
if(nodes == 1)
return ;
while(pos)
{
dirxn = GETBIT(nodes,pos);
if(dirxn)
tmp = tmp->right;
else
tmp = tmp->left;
pos--;
}
dirxn = GETBIT(nodes,pos);
if(dirxn)
{
first->data = tmp->right->data;
free(tmp->right);
tmp->right = 0;
}
else
{
first->data = tmp->left->data;
free(tmp->left);
tmp->left = 0;
}
}
void heapSort(node *tmp)
{
if(!tmp->right && !tmp->left)
return;
if(!tmp->right)
{
if(tmp->left->data > tmp->data)
swap(&tmp->left->data, &tmp->data);
}
else
{
if(tmp->right->data > tmp->left->data)
{
if(tmp->right->data > tmp->data)
{
swap(&tmp->right->data, &tmp->data);
heapSort(tmp->right);
}
}
else
{
if(tmp->left->data > tmp->data)
{
swap(&tmp->left->data, &tmp->data);
heapSort(tmp->left);
}
}
}
}
I don't really understand the right shift operator
so I tried to replace for(i=nodes,j=-1; i; i >>= 1,j++);
with
int o, j=0;
for(int i=1;;i=pow(2, j)){
if(nodes<i){
o = j-1;
break;
}
j+=1;
}
but I don't understand dirxn = GETBIT(nodes,pos);
my question is what does this do?
and can anyone tell me what should I do to replace this with something without a shift operator?
any help will be greatly appreciated

How to insert multiple data in linked list

This program asks for two data ( a name and an id), and then stores them in a linked list and then it should output all the data one by one.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Test
{
char name[16];
int id;
};
typedef struct Node {
struct Test structure;
struct Node * next;
}TNode;
typedef TNodo* Node;
void NewDatainNode(struct Test p, Node *pp)
{
TNode *temp;
temp = malloc(sizeof(struct Node));
temp->structure = p;
temp->next = NULL;
*pp = temp;
}
void ReadData(struct Test * p)
{
printf("\nName:");
scanf(" %s", p->name);
printf("\nID:");
scanf(" %d", &p->id);
}
void ViewNodes(Node node)
{
while(node != NULL)
{
printf("%s %d\n",node->structure.name, node->structure.id);
node = node->next;
}
}
int Menu()
{
int c;
printf("\n\tM E N U ***\n"
"1 - New\n"
"2 - Print\n"
"0 - Exit\n"
"\n>> ");
scanf(" %d", &c);
return c;
}
int main()
{
int c;
struct Prova test;
struct Node * list = NULL;
do {
c = Menu();
switch (c)
{
case 1: ReadData(&test);
NewDatainNode(test, &list);break;
case 2: ViewNodes(lista); break;
default: c = 0;
}
} while (c != 0);
return 0;
}
The problem is that it outputs only the last data that has been inserted, what should i do to make it output all the data retrieved in function NuovaPrenotazione()?.
UPDATE: Now the function NewDatainNodes() looks like this:
void NewDatainNode(struct Test p, Node *pp)
{
TNode *temp;
temp = malloc(sizeof(struct Node));
temp->structure = p;
temp->next = *pp;
*pp = temp;
}
Thanks to Sandeep for the correction, the function works even without a return value,the problem was temp->structure = NULL.
This question is exactly duplicate copy of a question posted yesterday and marked as duplicate. But, here is your working code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
struct Prova
{
char nome[16];
int id;
};
typedef struct Node {
struct Prova struttura;
struct Node * next;
}TNodo;
typedef TNodo* Nodo;
Nodo NuovaPrenotazione(struct Prova p, Nodo pp)
{
Nodo temp;
temp = (Nodo)malloc(sizeof(struct Node));
temp->struttura = p;
temp->next = pp;
pp = temp;
return pp;
}
void LeggiPrenotazione(struct Prova * p)
{
printf("\nNome Cliente:");
scanf(" %s", p->nome);
printf("\nID:");
scanf(" %d", &p->id);
}
void Visualizza(struct Prova p)
{
printf("%s %d\n", p.nome, p.id);
}
void VisualizzaPrenotazione(Nodo nodo)
{
while(nodo != NULL)
{
Visualizza(nodo->struttura);
nodo = nodo->next;
}
}
int Menu()
{
int scelta;
printf("*** M E N U ***\n"
"1 - New\n"
"2 - Print\n"
"0 - Esci\n"
"Scelta --> ");
scanf(" %d", &scelta);
return scelta;
}
int main()
{
int scelta;
struct Prova test;
Nodo lista = NULL;
do {
scelta = Menu();
switch (scelta)
{
case 1: LeggiPrenotazione(&test);
lista = NuovaPrenotazione(test, lista);
break;
case 2: VisualizzaPrenotazione(lista); break;
default: scelta = 0;
}
} while (scelta != 0);
return 0;
}
Update: Here is the output

expected ')' before '*' token passing in Node

I've searched this question and the previous ones do not seem to be related to my problem. I seem to have a disconnect on passing a node into a function, for some reason I keep getting this error when attempting to compile.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
char c;
int titleCount;
int authorCount;
char bookTitle[35];
char author[35];
/* Create Struct */
typedef struct bookData {
char bookTitle[35];
char author[35];
int book_stock;
float retail_price;
int wholesale_purchased;
int customer_purchased;
struct bookData *book;
} new_book;
/*Create Node */
typedef struct Node {
new_book books;
struct Node *next;
} node_t;
/* We are GUARANTEED at least 1 input value, so go ahead and initialize the head */
node_t *head = NULL; /*Initalize head to NULL since it is empty */
head = malloc(sizeof(node_t));
if(head == NULL) {
printf("allocation failed");
return 0;
}
head -> next = NULL;
/*Memory allocation successful */
/*Might as well populate the head with data from the user */
titleCount = 0;
authorCount = 0;
printf("Enter Title\n");
while(( c = getchar()) != '\n') {
bookTitle[titleCount++] = c;
}
bookTitle[titleCount] = '\0';
printf("%s\n", bookTitle);
strcpy(head -> books.bookTitle, bookTitle);
printf("Enter Author\n");
while(( c = getchar()) != '\n') {
author[authorCount++] = c;
}
author[authorCount] = '\0';
strcpy(head -> books.author, author);
printf("Bookstock #:\n");
scanf("%d", &(head -> books).book_stock);
printf("Enter retail price $:\n");
scanf("%f", &(head -> books).retail_price);
printf("Enter Wholesale purchased quanity:\n");
scanf("%d", &(head -> books).wholesale_purchased);
printf("Enter quantity sold:\n");
scanf("%d", &(head -> books).customer_purchased);
printf("%s\n", head -> books.bookTitle);
printf("%s\n", head -> books.author);
printf("%d\n", head -> books.book_stock);
printf("%.2f\n", head -> books.retail_price);
printf("%d\n", head -> books.wholesale_purchased);
printf("%d\n", head -> books.customer_purchased);
takeUserInput(head);
}
/*Now populate all other nodes, until user enters END_DATA */
void takeUserInput(node **head) {
int titleCount;
int authorCount;
char bookTitle[35];
char author[35];
int flag = 0;
while(1) {
titleCount = 0;
authorCount = 0;
node_t *temp = NULL;
temp = malloc(sizeof(node_t));
temp -> next = NULL;
printf("Enter Title\n");
while(( c = getchar()) != '\n') {
bookTitle[titleCount++] = c;
}
bookTitle[titleCount] = '\0'
if(bookTitle == "END_DATA") {
flag = 1;
break;
}
strcpy(temp -> books.bookTitle, bookTitle);
printf("Enter Author\n");
while(( c = getchar()) != '\n') {
author[authorCount++] = c;
}
author[authorCount++] = '\0';
strcpy(temp -> books.author, author);
printf("Bookstock #\n");
scanf("%d", &(temp - > books).book_stock);
printf("Enter retail Price in $\n:");
scanf("%.2f", &(temp -> books).retail_price);
printf("Enter wholesale purchased\n:");
scanf("%d", &(temp -> books).wholesale_purchased);
printf("Enter customer purchased\n:");
scanf("%d", &(temp -> books).customer_purchased);
if(temp -> books.book_stock < head -> books.book_stock) {
void pushToFront(head, temp);
} else {
void insert(head,temp);
}
}
if(flag == 1) {
free(temp);
}
}
void pushToFront(node_t **head, node_t *temp) {
temp -> next = *head;
*head -> temp;
}
void insert(node_t *head, node_t *temp) {
node_t *current = head;
while(current -> next -> new_book.book_stock < temp -> new_book.book_stock || current -> != NULL) {
current = current -> next;
}
if(current -> next = NULL) {
current -> next = temp;
}
node_t *xtraNode = current -> next
current -> next = temp;
temp -> next = xtraNode;
}
Error:
lab3p1.c:114: error: expected ‘)’ before ‘*’ token
lab3p1.c:180: error: expected ‘)’ before ‘*’ token
lab3p1.c:188: error: expected ‘)’ before ‘*’ token
To my understanding, I only need to pass in a double pointer when I'm adjusting which node the head points to pushToFront. So on insert(), I'm not actually adjusting the head pointer, just the next pointer of a particular node and the node being inserted. So I'm a little confused as to why this error is occurring.
I have spent a bit time to try compile your code but the number of errors is astonishing. Your code requires your serious attention.
Start with the simple things first.
First move the declaration of the structures before main:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/* Create Struct */
typedef struct bookData{
char bookTitle[35];
char author[35];
int book_stock;
float retail_price;
int wholesale_purchased;
int customer_purchased;
struct bookData *book;
}new_book;
/*Create Node */
typedef struct Node{
new_book books;
struct Node *next;
}node_t;
void takeUserInput(node_t **head);
void pushToFront(node_t **head, node_t *temp);
void insert(node_t *head, node_t *temp);
int main(){
//...
}
and put your function prototypes before main as well.
void takeUserInput(node **head){
should be:
void takeUserInput(node_t **head){
and
takeUserInput(head);
should be:
takeUserInput(&head);
and
void takeUserInput(node_t **head){ // node_t not node sg7
int titleCount;
int authorCount;
char bookTitle[35];
char author[35];
int c; // declaration was missing sg7!
later
bookTitle[titleCount] = '\0' // missing ;
if(bookTitle == "END_DATA"){ // this is NOT the way to compare strings
I also noticed that you have not accepted a single answer, yet.
I have stopped here and I let you continue yourself. Good luck. Everyone has to carry his own cross.

Traversing and printing a queue in C behaves differently when input is given by the user

I apologise if this concept has been explained on SOF before! I believe my case is slightly different and couldn't find a similar question in the website.
Here's the problem:
I'm trying to store char arrays (strings) in a Queue structure that I'm trying to implement.
The structure and its functions seem to work fine when I hardcode the data myself like this:
#include "Time.h"
#include <unistd.h>
int main(void){
struct Queue* q = CreateQueue();
Enqueue(q, "element1");
Enqueue(q, "element2");
Enqueue(q, "element3");
Enqueue(q, "element4");
PrintAll(q->first); // this outputs all elements and the time they've been in the queue.
return 0;
}
The output is as expected, a list of all 4 elements.
However, as soon as I put a simple menu together, to capture the data from the user instead of it being hardcoded as above, the PrintAll() function outputs a duplicate of the very last element enqueued. You also notice that I am timing each node to keep a track on when it was added to the queue and that seem to work fine. Although the ouput shows the last element entered duplicated N times (N being the size of the queue) the timer seems to show correctly for each node!
I am suspecting it's to do with the stdin stream that is not being cleaned but I thought I handled that with a block of code that is shown in main() function.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void){
char name[31];
char c;
int option;
int ch;
struct Queue* q = CreateQueue();
do
{
printf("\n 1. Add a an element to the queue");
printf("\n 2. Print all elements");
printf("\n 0. Exit");
printf("\n Please select an option");
while(scanf("%d", &option)!=1){
puts("Value non good");
ch=getchar();
while(ch!=EOF && ch!='\n'){
ch=getchar();
}
}
switch(option)
{
case 1:
{
ch=getchar();
while(ch!=EOF && ch!='\n')
{
ch=getchar();
}
printf("Please enter the name of the element.\n ");
fgets(name,30,stdin);
Enqueue(q, name);
PrintAll(q->first);
break;
}
case 2:
{
PrintAll(q->last);
break;
}
default:
return 0;
}
}while(option != 0);
return 0;
}
Can anybody please shed light on the problem ? I would appreciate it.
here's the rest of the code:
Time.c:
#include "Time.h"
struct Queue* CreateQueue()
{
struct Queue* q = malloc(sizeof(struct Queue));
q->first = NULL;
q->last = NULL;
q->size = 0;
return q;
}
void Enqueue(struct Queue* queue, char* string)
{
struct Node* newNode = malloc(sizeof(struct Node));
newNode->next = NULL;
newNode->student = string;
newNode->start_time = time(0);
if(queue->size == 0)
{
queue->first = newNode;
}
else
{
queue->last->next = newNode;
}
queue->last = newNode;
queue->size = queue->size + 1;
}
char* Dequeue(struct Queue* queue)
{
if (queue->size < 0)
{
exit(0);
}
char* toBeRemoved = queue->first->student;
struct Node* oldNode = queue->first;
queue->first = oldNode->next;
queue->size = queue->size - 1;
if(queue->size == 0)
{
queue->last = NULL;
}
free(oldNode);
return toBeRemoved;
}
int IsEmpty(struct Queue *q)
{
return q->size == 0;
}
char* Peek(struct Queue *q)
{
return q->first->student;
}
void PrintOne(struct Node *node)
{
if(node !=NULL)
{
int elapsed = ElapsedTime(node);
printTime(elapsed, node->student);
//printf("%s\n", node->student);
}
}
void PrintAll(struct Node* node)
{
if (node !=NULL)
{
PrintAll(node->next);
PrintOne(node);
}
}
// returns the waiting time for a student node.
int ElapsedTime(struct Node* node)
{
int elapsed;
time_t stop_time;
stop_time = time(NULL);
elapsed = difftime( stop_time , node->start_time );
return elapsed;
}
void printTime(int elapsed, char* student_name)
{
printf("%s : waiting for ", student_name);
int minutes_or_hours = 0; //Stores a zero to indicate that it is not neccesary to print minutes or hours.
//Stores a one to indicate that hours and/or minutes have been printed.
if( (elapsed / 3600) >= 1)
{
int hours = elapsed/3600;
if(hours == 1)
{
printf("1 hour, ");
}
else
{
printf("%d hours, ", hours);
}
elapsed = elapsed - (hours*3600);
minutes_or_hours = 1;
}
if( (elapsed / 60) >= 1)
{
int minutes = elapsed/60;
if(minutes == 1)
{
printf("1 minute, ");
}
else
{
printf("%d minutes, ", minutes);
}
minutes_or_hours = 1;
elapsed = elapsed - (minutes*60);
}
if(minutes_or_hours == 1)
{
printf("and ");
}
printf("%d seconds\n", elapsed);
}
Time.h:
#ifndef TIME_H_
#define TIME_H_
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
struct Node
{
time_t start_time;
struct Node* next;
char* student;
};
struct Queue
{
int size;
struct Node* first;
struct Node* last;
};
struct Queue* CreateQueue();
void Enqueue(struct Queue* , char* );
char* Dequeue(struct Queue* );
int IsEmpty(struct Queue *);
char* Peek(struct Queue *);
void PrintOne(struct Node *);
void PrintAll(struct Node *);
int ElapsedTime(struct Node* );
void printTime(int , char* );
#endif /* TIME_H_ */
In the function Enqueue() you have only copied the string pointer to your structure. In your first case that works, because all the four strings have different pointers to string literals. But in your second example, you are storing the pointer of your data entry name, and the contents of this string change with each entry. Each structure store the same pointer, so all point to the most recent string you typed in. If your struct stored the actual string, it would work (but you need to be careful with string lengths).
struct Node
{
time_t start_time;
struct Node* next;
char student[31];
};
void Enqueue(struct Queue* queue, char* string)
{
...
strncpy (newNode->student, 30, string);
...
}

Doubly linked list: Incompatible pointer types

at the moment I'm working on an implementation of a balanced B-Tree in C. I decided to use doubly linked lists but I have run into some problems. At the moment I get warnings for line 94, 95 and 96 because apparently the pointer types are incompatible.
I really don't see how and any help would be greatly appreciated.
#include <stdio.h>
#include <stdlib.h>
typedef struct {
int data1;
int data2;
int data2exists; // no: 0 , yes: 1
struct node * parent;
struct node * left;
struct node * middle;
struct node * right;
} node;
node * insert(int *, node *, node *);
void getInput(int *);
node * createNode(int *);
void quickSwap(node *, int *, int *, int *, int *);
node * splitLeaf(int *, int *, int *, node *, node *);
void printTree(node *);
void main() {
int input;
getInput(&input);
node * root = createNode(&input);
getInput(&input);
insert(&input, root, root); // returns current pos
getInput(&input);
insert(&input, root, root); // returns current pos
getInput(&input);
insert(&input, root, root); // returns current pos
printTree(root);
}
node * insert(int * input, node * root, node * currentPos) {
printf("data1: [%i], data2: [%i], d2exists: [%i], input: [%i]\n", currentPos->data1, currentPos->data2, currentPos->data2exists, *input);
if (currentPos->left == NULL && currentPos->middle == NULL && currentPos->right == NULL) {
// no children
if (*input > currentPos->data1 && currentPos->data2exists == 0) {
// data1 < input, no data2
currentPos->data2 = *input;
currentPos->data2exists = 1;
return(currentPos);
// printf("CASE1: data1 < input, no data2, no children\n");
}
if (*input < currentPos->data1 && currentPos->data2exists == 0) {
// data1 > input, no data2
currentPos->data2 = currentPos->data1;
currentPos->data1 = *input;
currentPos->data2exists = 1;
return(currentPos);
// printf("CASE2: data1 > input, no data2, no children\n");
}
if (currentPos->data2exists == 1) {
// data2 exists
int smallest;
int middle;
int largest;
quickSwap(currentPos, input, &smallest, &middle, &largest);
printf("s: [%i] m: [%i] l: [%i]\n", smallest, middle, largest);
root = splitLeaf(&smallest, &middle, &largest, currentPos, root);
}
}
return(currentPos);
}
void printTree(node * root) {
if (root->parent != NULL) {
printf("printTree() did not receive root!!!!\n");
return;
}
else {
printf("%i || %i", root->data1, root->data2);
printf("\n");
// printf("%i || %i", root->left->data1, root->left->data2);
// printf("\t\t");
// printf("%i || %i", root->middle->data1, root->middle->data2);
// printf("\t\t");
// printf("%i || %i", root->right->data1, root->right->data2);
// printf("\n");
}
}
node * splitLeaf(int * smallest, int * middle, int * largest, node * currentPos, node * root) {
// this function needs to return root!
if (currentPos->parent == NULL) {
// currentPos is root
// create a parent with median
node * root = createNode(middle);
node * left = createNode(smallest);
node * middle = createNode(largest);
// genau hier gehts weiter! hier müssen root, left und, middle verknüpft werden!
root->left = left;
root->middle = middle;
left->parent = middle->parent = root;
// printf("root-addr: %i, left->parent: %i\n", root, left->parent);
return(root);
}
}
void quickSwap(node * currentPos, int * input, int * smallest, int * middle, int * largest) {
// writes values to *smallest, *middle and *largest ordered by size
if (currentPos->data1 > currentPos->data2) {
*smallest = currentPos->data2;
*middle = currentPos->data1;
}
else {
*smallest = currentPos->data1;
*middle = currentPos->data2;
}
if (*input < *smallest) {
*largest = *middle;
*middle = *smallest;
*smallest = *input;
}
else if (*input < *middle) {
*largest = *middle;
*middle = *input;
}
else {
*largest = *input;
}
}
node * createNode(int * input) {
node * ptr = (node*) malloc(sizeof(node));
ptr->data1 = * input;
ptr->data2 = 0;
ptr->data2exists = 0;
ptr->parent = NULL;
ptr->left = NULL;
ptr->middle = NULL;
ptr->right = NULL;
return(ptr);
}
void getInput(int * input) {
printf("Enter a number\n");
scanf(" %i",input);
}
Aha! The problem is a tricky one. It has to do with the definition of your node struct. The members parent, left, middle and right are of type struct node but you typedefed the struct to be node directly. My guess is that GCC ignores the undefined struct node and hopes it's defined somewhere else.
In other words: the type node exists, but struct node doesn't. Therefore when you try to assign a node to a struct node GCC doesn't know what to do. So change
typedef struct {
...
} node;
to
typedef struct node {
...
} node;
Although it might be wiser to use another name for the struct node than the type node.
Some nitpicks:
GCC complains that main doesn't return an int (just return 0;)
In splitLeaf you're redeclaring the arguments int * middle to node * middle and the same with root.
splitLeaf doesn't return anything when currentPos->parent isn't NULL (though maybe you haven't finished the function yet)

Resources