So I'm confident that this c implementation of a linked list is flawed in a few areas. My question is primarily this, though any other help is appreciated; I know that the code will run to completion and print the output properly. However, upon adding another function accessed later in the code, the code will lock up before that point is even reached. I was wondering why this is, and how to fix it. I will include the text from all the files below, but for this assignment in particular I can only edit printandcombine.c and its headerfile.
printandcombine.h
:
//Riley Branting
#ifndef PRINTANDCOMBINE_H
#define PRINTANDCOMBINE_H
//Returns a string representation of the struct term_t
char * term_to_string(term_t * term);
//Prints a linkedlist in no specific order
void print_linklist(node_t * curr);
//Returns a new linkedlist that is the result of combining the like terms
node_t * combine_like_terms(const node_t * current_node_ptr);
#endif
printandcombine.c
:
// Riley Branting
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
// Returns a string representation of the struct term_t
char *term_to_string(term_t *term) {
// printf("term_to_string 1");
char *str = malloc((sizeof(int)) * 4);
// printf("term_to_string 2");
sprintf(str, "%d%c%d ", term->coefficient, term->var, term->exponent);
printf("%s", str);
// printf("term_to_string 3");
return str;
}
// Prints a linkedlist in no specific order
void print_linklist(node_t *curr) {
// printf("print_linkedlist 1");
printf("%s", term_to_string(curr->term));
// printf("print_linkedlist 2");
if (!(curr->next_node == NULL)) {
print_linklist(curr->next_node);
}
// printf("print_linkedlist 3");
}
// Returns a new linkedlist that is the result of combining the like terms
node_t *combine_like_terms(const node_t *current_node_ptr) {
node_t *temp = (node_t *)current_node_ptr;
node_t *out = malloc(sizeof(node_t));
node_t *move = out;
int x = 0;
while (!(temp == NULL)) {
if (temp->term->exponent > x) {
x = temp->term->exponent;
temp = temp->next_node;
}
}
for (; x >= 0; x--) {
temp = (node_t *)current_node_ptr;
int a = 0;
while (!(temp == NULL)) {
if (temp->term->exponent == x) {
a = a + temp->term->coefficient;
}
move->term->coefficient = a;
move->term->var = 'x';
move->term->exponent = x;
if (x > 0) {
move->next_node = (node_t *)malloc(sizeof(node_t));
move = move->next_node;
}
} // end while loop
} // end for loop
return out;
}
project.c
:
/* This is your main file */
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"common.h"
#include"buildlinklist.h"
#include"printandcombine.h"
int main() {
node_t * node_ptr = NULL;
node_t * new_node_ptr=NULL;
printf("NAME: Riley Branting\n");
/* Build linklist */
read_objects(&node_ptr);
/* Print the link list */
printf("Original: ");
print_linklist(node_ptr);
/* Combine like terms in the link list and craeate a new link list */
new_node_ptr=combine_like_terms(node_ptr);
printf("\nCombined: : ");
/* Print new combine linklist */
print_linklist(new_node_ptr);
printf("\nRiley Branting\n");
free(node_ptr);
free(new_node_ptr);
return 0;
}
sidenote: It is very unlikely these last files are too important, but i'm adding them just in case
buildlist.h
:
#ifndef BUILDLINKLIST_H
#define BUILDLINKLIST_H
#include"common.h"
/* Read from a text file and put in to a term_t structure. Then create a linklist of node (each node has an element of term struct.)*/
void read_objects(node_t ** pointer_to_node_ptr);
/* Assign value to term_t object elements */
term_t * term_from_string(char * buff);
/* Add a node to the link list */
int add_node(node_t ** pointer_to_node_ptr, void * term);
#endif
buildlist.c
:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include"common.h"
/* Assign value to term_t object elements */
term_t * term_from_string(char * buff) {
term_t * ret = malloc(sizeof(term_t));
ret->coefficient=atoi(strtok(buff, " "));
ret->var=*strtok(NULL, " ");
ret->exponent=atoi(strtok(NULL, " "));
return ret;
}
/* Add a node to the link list */
int add_node(node_t ** pointer_to_node_ptr, void * term) {
int ret = 0;
node_t * newnode_ptr = (node_t *) malloc(sizeof(node_t));
if (newnode_ptr == NULL) {
ret = -1;
}
else {
newnode_ptr->term = term;
newnode_ptr->next_node = *pointer_to_node_ptr;
*pointer_to_node_ptr = newnode_ptr;
}
return ret;
}
/* Read from a text file and put in to a term_t structure. Then create a linklist of node (each node has an element of term struct.)*/
void read_objects(node_t ** pointer_to_node_ptr) {
FILE *fp;
char buffer[BUFFERLEN];
fp = fopen("terms.txt", "r");
while (fgets(buffer, BUFFERLEN,fp)) {
term_t * this_term;
this_term = term_from_string(buffer);
add_node(pointer_to_node_ptr, this_term);
}
fclose(fp);
}
common.h
:
#ifndef COMMON_H
#define COMMON_H
#define BUFFERLEN 40
typedef struct{ /* struct to hold elements like: 3x4 */
int coefficient;
char var;
int exponent;
} term_t;
typedef struct node {
term_t * term; /* pointer to term */
struct node * next_node; /* pointer to next node */
} node_t;
#endif
And finally, this is the make file i'm using:
CC=gcc
CFLAGS=-std=c11 -Wall -pedantic
all: project1.c buildlinklist.o printandcombine.o
$(CC) $(CFLAGS) project1.c buildlinklist.o printandcombine.o -o project1
buildlinklist.o: buildlinklist.c
$(CC) $(CFLAGS) -c buildlinklist.c
printandcombine.o: printandcombine.c
$(CC) $(CFLAGS) -c printandcombine.c
clean:
rm -f *.o *~ project1.exe