This is the source code:
#include <stdio.h>
#include <stdlib.h>
struct Fraction{
int num;
int denom;
};
typedef struct Fraction Frac;
typedef Frac* FracPtr;
struct FracNode {
Frac fr;
struct FracNode* next;
};
typedef struct FracNode FrNode;
typedef FrNode* FrNodePtr;
struct FracStack {
int stkSize;
FrNodePtr frNodePtr;
};
typedef struct FracStack FrStk;
typedef FrStk* FrStkPtr;
FrNodePtr createFrNode(void);
FrStkPtr createFrNodeStk(void);
void pushFrNode(FrStkPtr*, FrNodePtr);
void printStack(FrStkPtr);
int main() {
FrNodePtr frNodeTmpPtr = 0;
FrNodePtr frNodeTmpPtr2 = 0;
FrStkPtr frStkPtr = 0;
frNodeTmpPtr = createFrNode();
frStkPtr = createFrNodeStk();
pushFrNode(&frStkPtr, frNodeTmpPtr);
printStack(frStkPtr);
frNodeTmpPtr2 = createFrNode();
pushFrNode(&frStkPtr, frNodeTmpPtr2);
printStack(frStkPtr); // Only the newly created fraction is printed. frNodeTmpPtr didn't get printed as part of the stack. Is there an issue with my print function or the push function?
free (frNodeTmpPtr);
free (frNodeTmpPtr2);
free (frStkPtr);
return 0;
}
//Print Stack
void printStack(FrStkPtr stkPtr) {
while (stkPtr->frNodePtr != 0) {
printf("Numerator: %d & Denominator: %d\n\n", stkPtr->frNodePtr->fr.num, stkPtr->frNodePtr->fr.denom);
stkPtr->frNodePtr = stkPtr->frNodePtr->next;
}
return;
}
//Push Node
void pushFrNode(FrStkPtr* stkPtr, FrNodePtr nPtr) {
if ((*stkPtr)->frNodePtr != 0) {
nPtr->next = ((*stkPtr))->frNodePtr;
}
(*stkPtr)->frNodePtr = nPtr;
(*stkPtr)->stkSize++;
return;
}
//Create Stack
FrStkPtr createFrNodeStk() {
FrStkPtr frStkPtr;
frStkPtr = (FrStkPtr) malloc (sizeof(FrStk));
frStkPtr->stkSize = 0;
frStkPtr->frNodePtr = 0;
return frStkPtr;
}
//Create Node
FrNodePtr createFrNode() {
FrNodePtr frNodePtr;
frNodePtr = (FrNodePtr) malloc (sizeof(FrNode));
frNodePtr->next = 0;
printf("Enter the numerator: ");
scanf("%d", &(frNodePtr->fr.num));
do {
printf("\nEnter a non-zero denominator: ");
scanf("%d", &(frNodePtr->fr.denom));
if (frNodePtr->fr.denom < 0) {
frNodePtr->fr.denom = -(frNodePtr->fr.denom);
frNodePtr->fr.num = -(frNodePtr->fr.num);
}
} while (frNodePtr->fr.denom == 0);
return frNodePtr;
}
In main, i created one fraction, pushed it into the created stack. Print it out. Then, i created another fraction, pushed it into the stack and print it. The problem is when i print out the stack it only prints out the last fraction created, not both fractions.
Sample run:
Enter the numerator: 1
Enter a non-zero denominator: 1
Numerator: 1 & Denominator: 1
Enter the numerator: 2
Enter a non-zero denominator: 2
Numerator: 2 & Denominator: 2 //I want this part to print out 1/1 and 2/2 not just 2/2
Change the printing function to the following:
//Print Stack
void printStack(FrStkPtr stkPtr) {
FrNodePtr pointer = stkPtr->frNodePtr;
while (pointer != 0) {
printf("Numerator: %d & Denominator: %d\n\n", pointer->fr.num, pointer->fr.denom);
pointer = pointer->next;
}
return;
}
Related
I'm trying to write a code that dynamically writes the Coordinates of a Point on the Stack and prints (and frees) them back:
#include <stdio.h>
#include <stdlib.h>
struct point{
float x;
float y;
float z;
}; typedef struct point POINT;
struct stackPoint{
POINT myPoint;
struct stackPoint *next;
}; typedef struct stackPoint STACKPOINT;
static STACKPOINT *stacktop = NULL;
void printStackElement(POINT aPoint){
printf(" x:%f \t y:%f \t z:%f\n", aPoint.x, aPoint.y, aPoint.z );
}
void push(POINT pushPoint){
STACKPOINT *newElem = malloc(sizeof(STACKPOINT));
stacktop = stacktop +1;
newElem->myPoint = pushPoint;
stacktop = newElem;
}
POINT pop(){
POINT b = stacktop->myPoint;
free(stacktop);
stacktop = stacktop -1;
return b;
}
int isEmpty(){
if(stacktop == NULL){
return 1;
}
return 0;
}
POINT readPoint(){
POINT a;
printf("Please enter your x-Coordinate: ");
scanf(" %f", &a.x);
printf("Please enter your y-Coordinate: ");
scanf(" %f", &a.y);
printf("Please enter your z-Coordinate: ");
scanf(" %f", &a.z);
return a;
}
int main(){
char quit = 0;
while(quit !=1 ){
printf("\n\n enter 'p' to enter another Point or 'q' to quit: " );
scanf(" %s", &quit);
switch(quit){
case 'p':
push(readPoint());
break;
case 'q':
quit = 1;
break;
default:
break;
}
}
while(isEmpty() == 0){
printStackElement(pop());
}
}
It prints the last entry but before printing the second to last entry, just an error message appears, that the "pointer beeing freed was not allocated".
I tried running it without the free() command, but then it just prints the first line and infite lines of just 0's
I also tried using the *stackTop pointer as a non static pointer instead of the *newElem pointer but that also didnt work..
It is supposed to be a linked list. Our professor just gave us this exercise and never even mentioned a linked list in any way or form.. Thank you very much, it works now!
I changed the push function to:
STACKPOINT *newElem = malloc(sizeof(STACKPOINT));
newElem->myPoint = pushPoint;
newElem->next = stacktop;
stacktop = newElem;
and the pop function to:
POINT b = stacktop->myPoint;
free(stacktop);
stacktop = stacktop->next;
return b;
This might be a dumb question but basically this program which uses pointer lists but stops execution after the first use of my showliste function which I use to I print out the list and I have no idea why. If I remove the showliste function then it runs the rest of the code just fine however I really have no idea why since I don't modify anything in that function and its only purpose is to print out the elements.
If somebody could help me out that would be very useful. Thank you in advance!
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define max 10
struct book{
char name[50];
float price;
struct book *next;
};
typedef struct book BOOK;
BOOK * createlist(BOOK *);
void showliste(BOOK *);
BOOK * deleteElem(BOOK *);
int main()
{
BOOK *pstart = NULL;
pstart = createlist(pstart);
printf("\nHere is the ordered list: \n");
showliste(pstart); //stops excution after this for some reason
pstart = deleteElem(pstart);
printf("\nHere is the list with the element deleted: \n");
showliste(pstart);
return 0;
}
BOOK * createlist(BOOK *pdebut)
{
int i, choice = 0;
BOOK *pparcour = NULL, *pprecedent = NULL, *pnew = NULL;
for(i = 0; i < max && choice == 0; i++)
{
pnew = (BOOK *)malloc(sizeof(BOOK));
printf("Enter name: ");
fflush(stdin);
gets(pnew->name);
printf("Enter Price: ");
scanf("%f", &pnew->price);
if(pdebut == NULL)
{
pdebut = pnew;
}
else{
pparcour = pdebut;
pprecedent = NULL;
while(pparcour != NULL && pnew->price > pparcour->price)
{
pprecedent = pparcour;
pparcour = pparcour->next;
}
if(pprecedent == NULL)
{
pnew->next = pparcour;
pdebut = pnew;
}
else{
pprecedent->next = pnew;
pnew->next = pparcour;
}
}
printf("Do you want to continue? \n");
printf("0 - Yes 1 - NO\n");
printf("Choice: ");
scanf("%d", &choice);
}
return pdebut;
}
void showliste(BOOK *pdebut)
{
while(pdebut != NULL)
{
printf("Name: %s\n", pdebut->name);
printf("Price: %.3f\n\n", pdebut->price);
pdebut = pdebut->next;
}
}
BOOK * deleteElem(BOOK *pdebut)
{
char cible[50];
BOOK *pprecedent = NULL, *pparcour = NULL;
printf("Enter the name of the book you want to delete: ");
fflush(stdin);
gets(cible);
pparcour = pdebut;
pprecedent = NULL;
while(pparcour != NULL && strcmpi(cible, pparcour->name))
{
pprecedent = pparcour;
pparcour = pparcour->next;
}
if(pparcour == NULL)
{
printf("\nEntered name is not in the list!!!!\n");
}
else{
if(pprecedent == NULL)
{
pdebut = pdebut->next;
free(pparcour);
}
else{
pprecedent->next = pparcour->next;
free(pparcour);
}
}
return pdebut;
}
pdebut is the head of the list.
pparcour is a pointer which I use to go through my list without modifying it.
pprecedent is basically the element just before pparcour, mainly used to add a new book in the correct position in a ordered list (if the price of the new book is smaller than the price located in pparcour->price)
These lines
pparcour = pdebut;
/* ... */
pparcour = pparcour->next;
setup access to the uninitialized next member of the recently malloc'd structure, which contains an indeterminate pointer value. Attempting to to read a price member via this indeterminate pointer value
while(pparcour != NULL && pnew->price > pparcour->price)
will invoke Undefined Behaviour on subsequent iterations of the loop.
Use calloc, or manually set the newly allocated node's next member to NULL.
for(i = 0; i < max && choice == 0; i++)
{
pnew = malloc(sizeof *pnew);
pnew->next = NULL;
/* ... */
I'm making simple patient managing program using circular queue but q.rear always have "0" value while executing exit_hos()
I thought that addq() makes variable "rear" different, but It doesn't work.
is_empty() always return front and rear is same.
I think I'm misunderstanding some codes and memory concepts.
how can I fix these functions?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 50
#define MAX_QUEUE_SIZE 6
typedef struct {
char** value;
int front;
int rear;
} Queue;
void init_queue(Queue* q) {
q->value = (char**)malloc(sizeof(char*) * MAX_QUEUE_SIZE);
q->front = 0;
q->rear = 0;
}
int is_full(Queue* q) {
if (((q->rear +1) % MAX_QUEUE_SIZE) == q->front)
return 1;
else
return 0;
}
int is_empty(Queue* q) {
if (q->front == q->rear)
return 1;
else
return 0;
}
void addq(Queue* q, char* value) {
q->rear = (q->rear+1) % MAX_QUEUE_SIZE;
q->value[q->rear] = value;
printf("addq: %s", value);
return;
}
char* deleteq(Queue* q) {
q->front = (q->front + 1) % MAX_QUEUE_SIZE;
return q->value[q->front];
}
void arrive(Queue q) {
int input;
char name[MAX_SIZE];
printf("\n");
printf("1. submit\n");
printf("2. cancel\n");
scanf("%d", &input);
if (input == 1) {
if (is_full(&q) == 1) {
printf("Service is not available\n");
}
else {
printf("name: ");
scanf("%s", name);
addq(&q, name);
}
}
else if (input == 2) {
return;
}
else {
printf("input error\n");
return;
}
return;
}
void exit_hos(Queue q) {
char patient[MAX_SIZE];
if (is_empty(&q) == 1)
{
printf("There is no patient waiting\n");
}
else {
strcpy(patient, deleteq(&q));
printf("patient: %s", patient);
}
return;
}
int main() {
int input;
Queue q;
init_queue(&q);
while (1)
{
printf("\nINPUT\n");
printf("1. Arrive hostpital\n");
printf("2. Exit hospital\n");
printf("3. service exit\n");
scanf("%d", &input);
if (input == 1)
arrive(q);
else if (input == 2) {
exit_hos(q);
}
else if (input == 3) {
printf("exit\n");
return 0;
}
else {
printf("input error\n");
}
}
free(q.value);
return 0;
}
I think that this line is wrong:
q->value = (char**)malloc(sizeof(char*) * MAX_QUEUE_SIZE);
I think that it should be:
char * _value = (char*)malloc(sizeof(char*) * MAX_QUEUE_SIZE);
q->value = &_value;
malloc is going to return a pointer to a char array. q->value is a pointer to a pointer to a char array. So you want to set it to the address of the char array that malloc is created for you.
Change you init_queue code to this and it will work:
void init_queue(Queue* q) {
char * _value = (char*)malloc(sizeof(char*) * MAX_QUEUE_SIZE);
q->value = &_value;
q->front = 0;
q->rear = 0;
}
Output:
Chris#DESKTOP-BCMC1RF ~
$ ./main.exe
INPUT
1. Arrive hostpital
2. Exit hospital
3. service exit
1
1. submit
2. cancel
1
name: fred
addq: fred
INPUT
1. Arrive hostpital
2. Exit hospital
3. service exit
2
If you already have a max queue size and a max size, you are better off pre-allocating the whole thing as an array, reducing memory headaches. As a general rule, avoid headaches unless they provide a feature you want.
Note: This method of keeping track of and re-using memory is called a circular buffer (not to be confused with the linked list types that are more commonly called queues).
#define MAX_SIZE 50
#define MAX_QUEUE_SIZE 6
typedef struct {
char value [MAX_QUEUE_SIZE][MAX_SIZE + 1]; //+1 to hold extra null termination
unsigned int front;
unsigned int size; //size is a clearer than rear, which could have meant end item or end+1 and needed special empty queue handling
} Queue;
void init_queue(Queue* q) {
memset(q,0,sizeof(Queue)); //just zero it all
//more info on this and some situation-dependent alternatives https://stackoverflow.com/questions/11152160/initializing-a-struct-to-0
}
int is_full(const Queue* q) {
return q->size >= MAX_QUEUE_SIZE;
}
int is_empty(const Queue* q) {
return q->size == 0;
}
//sometimes called a push operation
//return 0 if failed
int addq(Queue* q, const char* value) {
//error check, abort, error handling section:
//full queue -> abort
if(is_full(q)) return 0;
//long value -> truncate handled via strncpy
//actual operation
const unsigned int destination = (q->front + q->size) % MAX_QUEUE_SIZE;
strncpy(q->value[destination],value,MAX_SIZE);
q->size = q->size + 1;
printf("addq: %s", q->value[destination]);
return q->size;
}
//sometimes called a pop operation
//return value may not persist if addq is called, but fine for your use of copying on call
const char* deleteq(Queue* q) {
if(is_empty(q)) return 0;
const char * retval = q->value[q->front];
q->front = (q->front + 1) % MAX_QUEUE_SIZE;
q->size = q->size - 1;
return retval;
}
also remember to use either MAX_SIZE + 1 or strncpy with MAX_SIZE - 1 since "No null-character is implicitly appended at the end of destination if source is longer than num."
(and strcpy and scanf as you sling them onto arrays is unsafe)
I'm trying to do a implementation of a deque with dynamic allocation, but I'm having some trouble since the values of the variables in the struct are different out of the function initialize, and I dont know why.
By some reason, the program always end up with a segmentation fault in the push_front/back part.
// C program for vetor implementation of d
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int data;
// A structure to represent a d
typedef struct deque
{
int front, rear, size;
unsigned int capacidade;
data* vetor;
}deque;
// function to create a d of given capacidade.
// It initializes size of d as 0
void initialize(deque *d, unsigned int capacidade){
d = (deque*) malloc(sizeof(deque));
d->capacidade = capacidade;
d->front = 0;
d->size = 0;
d->rear = capacidade-1; // This is important, see the enqueue
d->vetor = (data*) malloc(d->capacidade * sizeof(data));
}
// deque is full when size becomes equal to the capacidade
int full(deque* d){
if(d->size == d->capacidade)
return 1;
else return 0;
}
// deque is empty when size is 0
int empty(deque* d){
return (d->size == 0);
}
// Function to add an item to the d.
// It changes rear and size
int push_back(deque* d, int item){
if (full(&d))
return 0;
d->rear = (d->rear + 1)%d->capacidade;
d->vetor[d->rear] = item;
d->size = d->size + 1;
}
int push_front(deque* d, int item){
if (full(&d))
return 0;
d->front = (d->front - 1+d->capacidade)%d->capacidade;
d->vetor[d->front] = item;
d->size = d->size + 1;
}
// Function to remove an item from d.
// It changes front and size
int pop_front(deque* d){
if (empty(&d))
return 0;
int item = d->vetor[d->front];
d->front = (d->front + 1)%d->capacidade;
d->size = d->size - 1;
return item;
}
int pop_back(deque* d){
if (empty(&d))
return 0;
int item = d->vetor[d->rear];
d->rear = (d->rear - 1+d->capacidade)%d->capacidade;
d->size = d->size - 1;
return item;
}
// Function to get front of d
int front(deque* d)
{
if (empty(d))
return 0;
return d->vetor[d->front];
}
// Function to get rear of d
int rear(deque* d)
{
if (empty(d))
return 0;
return d->vetor[d->rear];
}
// Driver program to test above functions./
int main()
{
deque* d;
int operacoes=0, tamdeque=0, i=0;
char opcao[100];
scanf("%d %d", &operacoes, &tamdeque);
initialize(&d, tamdeque);
while(i<=operacoes){
scanf("%s", opcao);
if(!strcmp(opcao, "insereI")){
if(full(&d)){
printf("cheia\n");
}
else{
data item;
scanf("%d", &item);
printf("%u\n", &d->capacidade);
push_front(&d, item);
}
}
else if(!strcmp(opcao,"insereF")){
if(full(&d)){
printf("cheia\n");
}
else{
data item;
scanf("%d", &item);
push_back(&d, item);
}
}
else if(!strcmp(opcao, "removeI")){
if(empty(&d)){
printf("vazia\n");
}
else{
pop_front(&d);
}
}
else if(!strcmp(opcao, "removeF")){
if (empty(&d)){
printf("vazia\n");
}
else{
pop_back(&d);
}
}
i++;
}
return 0;
}
Mis-match arguments
In many places, the following type of error. Readily findable will all warnings enabled.
warning: passing argument 1 of 'pop_back' from incompatible pointer type [-Wincompatible-pointer-types]
int push_back(deque* d, int item){
// if (full(&d))
if (full(d))
main()
// deque* d;
deque d;
initialize(&d, tamdeque);
mixing int/unsigned math.
Recommend a design change to use just one.
Missing return value
Minor: int push_back(), push_front()
Other problems exist. (About 30 total warnings)
I will first add my code:
typedef struct _stack stack;
typedef struct _stack_element stack_element;
struct _stack {
stack_element* top;
};
struct _stack_element {
stack_element* next;
float value;
};
void stack_push(stack* astack, float value)
{
struct _stack_element *elem=calloc(1,sizeof(stack_element));
elem->value=value;
if(astack->top==NULL){
astack->top=elem;
}
else{
elem->next=astack->top;
astack->top=elem;
}
}
float stack_pop(stack* astack)
{
float Number;
if(astack==NULL){
Number=NAN;
return Number;
}
else{
Number=astack->top->value;
astack->top=astack->top->next;
}
return Number;
}
void process(stack* astack, char* token)
{
/* HIER implementieren */
// printf("\n<Logik fehlt!>\n");
if(is_number(token)==1){
float number=atof(token);
stack_push(astack, number);
}
if(is_add(token)==1){
float Number1=stack_pop(astack);
float Number2=stack_pop(astack);
float result=Number1+Number2;
stack_push(astack, result);
}
if(is_sub(token)==1){
float Number1=stack_pop(astack);
float Number2=stack_pop(astack);
float result=Number2-Number1;
stack_push(astack, result);
}
if(is_mult(token)==1){
float Number1=stack_pop(astack);
float Number2=stack_pop(astack);
float result=Number1*Number2;
stack_push(astack, result);
}
return;
}
void print_stack(stack *astack) {
int counter = 0;
printf("\n |xxxxx|xxxxxxxxxxxxxxxxxxx|xxxxxxxxxxxxxxxxxxx|xxxxxxxxx|\n");
printf(" | Nr. | Adresse | Next | Wert |\n");
printf(" |-----|-------------------|-------------------|---------|\n");
for (stack_element* elem=astack->top; elem != NULL; elem = elem->next) {
printf(" | %3d | %17p | %17p | %7.3f |\n", counter, elem, elem->next, elem->value);
counter++;
}
printf(" |xxxxx|xxxxxxxxxxxxxxxxxxx|xxxxxxxxxxxxxxxxxxx|xxxxxxxxx|\n");
}
stack* stack_erstellen() {
struct _stack* Stack =(struct _stack*)calloc(1, sizeof(struct _stack));
Stack->top=NULL;
return Stack;
}
int main(int argc, char** args)
{
stack* astack = stack_erstellen();
char zeile[MAX_STR];
char* token;
intro();
while (taschenrechner_input(zeile) == 0) {
// Erstes Token einlesen
token = strtok(zeile, " ");
while (token != NULL) {
printf("Token: %s\n", token);
// Stackoperationen durchführen return;
process(astack, token);
// Nächstes Token einlesen
token = strtok(NULL, " ");
print_stack(astack);
}
printf("\nExtrahiere Resultat\n");
float result = stack_pop(astack);
print_stack(astack);
if (astack->top != NULL) {
while (astack->top != NULL) {
stack_pop(astack); //Räume Stack auf
}
printf("\nDoes not Compute: Stack nicht leer!\n");
} else if (result != result) {
printf("\nDoes not Compute: Berechnung fehlgeschlagen!\n");
} else {
printf("\nDein Ergebnis:\t%7.3f\n\n", result);
}
}
free(astack);
}
I am new to coding. The code above is from a assignment for university. The function I had to create are:
void stack_push(stack* astack, float value)
void stack_pop(stack* astack)
void process (stack* astack, char* token)
stack* stack_erstellen() (this translated to "create_stack")
There is also another c file that is compiled together with this one but I am not allowed to change anything in so I did not add it to this post.
The calculator seems to work fine and the print_stack() function also suggests that the push and pop functions work as expected.
My problem is that I am not sure how to free the memory in the pop function that allocated in the push function. How do I free the elements of my stack?
am knew to describing technical problems like this so If anything lacks I'll gladly add more information.
My problem is that I am not sure how to free the memory in the pop function that allocated in the push function. How do I free the elements of my stack?
You need to save the next pointer before free()ing the element:
float stack_pop(struct _stack *astack) {
float Number;
if (astack == NULL) {
Number = NAN;
// return Number; // no need for return here
} else {
Number = astack->top->value;
struct _stack_element *tmp = astack->top->next; // save
free(astack->top); // free
astack->top = tmp; // restore
}
return Number;
}
I took the liberty of formatting your code to my liking :)
Also, consider using double instead of float.