1

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;
}
1
  • 1
    Adding to a queue only modifies the front and not the rear. Normally we call this a ring buffer and the pointers are called the head and the tail. Commented Sep 20, 2020 at 15:56

2 Answers 2

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
Sign up to request clarification or add additional context in comments.

4 Comments

So, I changed my answer after I compiled to make sure that I was right. ` q->value = (&(char*)malloc(sizeof(char*) * MAX_QUEUE_SIZE));` will give you a compiler error. So, I did it in two steps.
Thx, But I just had mistake that uploading with test code q.front = 0; q.rear = 1; in main() . I changed this and compiled with your code, but I think It still have errors with adding values in queue..
@crakel, tell give us an example of what input is creating a problem.
it just same when program execute exit_hos() , it doesn't work correctly (exactly addq()) and value of front, rear returns to 0
0

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)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.