I'm new to C and I'm trying to code a queue problem. At the moment, I'm coding something that will check if the queue is empty. This is what I have so far:
For Queue.h (this was provided by our instructor)
#include <stdio.h>
#include <stdlib.h>
struct queueNode {
char data;
struct queueNode *nextPtr;
};
typedef struct queueNode QueueNode;
typedef QueueNode* QueueNodePtr;
typedef struct Queue {
QueueNodePtr head;
QueueNodePtr tail;
} Queue;
void instructions();
int isEmpty(Queue);
void enqueue(Queue*, char);
char dequeue(Queue*);
void printQueue(Queue);
void freeQueue(Queue*);
For Queue.c
#include <stdio.h>
#include <stdlib.h>
#include "Queue.h"
int isEmpty(struct Queue queue)
{
if (Queue == NULL)
{
return 1;
}
}
The problem is in line 8 of Queue.c, the compiler says "error: expected expression before 'Queue'" How will I resolve this?
Edit: I tried to use queue == NULL instead of Queue == NULL and the compiler said: error: invalid operands to binary == (have 'struct Queue' and 'void*').
Thank you very much!
To begin with, use a consistent way of passing your queue around. Note the differences in the interfaces:
int isEmpty(Queue); //<-- by value
void enqueue(Queue*, char); //<-- by reference
char dequeue(Queue*); //<-- by reference
void printQueue(Queue); //<-- by value
void freeQueue(Queue*); //<-- by reference
Some of these are passing a Queue structure by value, and others by reference (pointer). It's likely that you want all your functions to operate on a pointer, i.e. Queue*.
Next, you should have some kind of operation that initializes the queue. You have freeQueue already, which does the inverse. So you probably want something like initQueue:
void initQueue(Queue* q) {
q->head = NULL;
q->tail = NULL;
}
Now, on to the actual question... As I've already suggested, you should change isEmpty (and printQueue) to accept a pointer to the queue. And then you use whatever logic should indicate the queue is empty. Since I've asserted above that on initialization, the head pointer should probably be NULL, then that would be an appropriate "empty" test as well:
int isEmpty(Queue* q) {
return q->head == NULL;
}
And finally, since you're likely to ask how to actually use this:
int main(void)
{
Queue q;
initQueue(&q);
printf("Queue empty: %d\n", isEmpty(&q));
enqueue(&q, 'X');
printf("Queue empty: %d\n", isEmpty(&q));
enqueue(&q, 'Y');
enqueue(&q, 'Z');
printQueue(&q);
printf("Removed %c\n", dequeue(&q));
printQueue(&q);
freeQueue(&q);
return 0;
}
Related
I need to reverse a stack using queue. The reverseStack() function only uses push()and pop()when adding or removing integers from the stack, and only uses enqueue() and dequeue() when adding or removing integers from the queue.
But I got a segmentation fault at push(&s, dequeue(&q));.
Could anyone tell me what does this mean? Thanks.
Here is my code:
void reverseStack(Stack *s)
{
Queue *q;
while(!isEmptyStack(s)) //pop items from stack and queue into q
{
enqueue(&q, pop(s));
}
while(!isEmptyQueue(q)) //dequeue items from queue and push to stack
{
push(&s, dequeue(&q));
}
}
Updated:
typedef struct _listnode{
int item;
struct _listnode *next;
} ListNode;
typedef struct _linkedlist{
int size;
ListNode *head;
ListNode *tail;
} LinkedList;
////////////////////////////////// stack ///////////////////////////////////////////////////////
typedef struct stack{
LinkedList ll;
} Stack;
//////////////////////////////////// queue ////////////////////////////////////////////////////////
typedef struct _queue{
LinkedList ll;
} Queue;
I was given these list of functions and I need to create the reverseStack() function based on these.
void push(Stack *s, int item){
insertNode(&(s->ll), 0, item);
}
int pop(Stack *s){
int item;
if(!isEmptyStack(s)){
item = ((s->ll).head)->item;
removeNode(&(s->ll), 0);
return item;
}
return INT_MIN;
}
int peek(Stack *s){
return ((s->ll).head)->item;
}
int isEmptyStack(Stack *s){
if ((s->ll).size == 0)
return 1;
return 0;
}
void enqueue(Queue *q, int item){
insertNode(&(q->ll), q->ll.size, item);
}
int dequeue(Queue *q){
int item;
item = ((q->ll).head)->item;
removeNode(&(q->ll), 0);
return item;
}
int isEmptyQueue(Queue *q){
if ((q->ll).size == 0)
return 1;
return 0;
}
There are several problems here.
Your reverseStack method is:
void reverseStack(Stack *s)
{
Queue *q;
while(!isEmptyStack(s)) //pop items from stack and queue into q
{
enqueue(&q, pop(s));
}
while(!isEmptyQueue(q)) //dequeue items from queue and push to stack
{
push(&s, dequeue(&q));
}
}
Here, you declare q, but you never define it. The first thing you need to do is make q point to something, or perhaps you meant to write:
Queue q;
Which would allocate space for a Queue structure on the processor stack.
With the code as written, I don't understand how it works. The calls to enqueue should die because q is never assigned a value. Although I guess it's possible, C being the friendly language it is, that since you're passing the address of q rather than the value of q, you're just corrupting the call stack.
In any event, unless you fix that (either make q a non-pointer, or assign it a value by calling malloc), you're going to have problems. If it really is supposed to be dynamically allocated, then replace &q with q in that function.
Your push is defined as:
void push(Stack *s, int item){
insertNode(&(s->ll), 0, item);
}
That says you need to pass a Stack * (pointer to a stack) as the first parameter.
But in your reverseStack function, s is already a Stack * (pointer to a stack). But you're calling push with the address of the pointer. You're passing a Stack ** (pointer-to-pointer to stack).
The correct call would be:
push(s, dequeue(q)); // or maybe dequeue(&q), depending on how you
// you end up defining q.
Your C compiler should have given you errors on those lines. Or ... well, C being what it is, perhaps it just gave you warnings.
A compiler warning is nothing more than an error in disguise. Compile with the highest possible warning level, enable the "warnings as errors" option, and fix every warning.
I'm creating a simple queue with simple operations. I use an ADT item to contain the informations, in this case only an int value. Then I use this item in the nodes. These are the files:
item.h
typedef struct c_item *item;
item newItem(int x);
int eq(item x, item y);
item input_item();
void output_item(item x);
char* getx(item x);
item cloneItem(item x);
item.c
#include <memory.h>
#include <stdio.h>
#include <stdlib.h>
#include "item.h"
struct c_item {
int x;
};
item newItem(int x){
item n = malloc(sizeof(struct c_item));
n->x=x;
return n;
}
int eq(item x, item y){
if (x->x==y->x)
return 1;
return 0;
}
item input_item(){
item n;
printf("Inserisci x: ");
scanf("%d", n->x);
return n;
}
void output_item(item x){
printf("x: %d\n", x->x);
}
item cloneItem(item x){
item n ;
n->x=x->x;
return n;
}
queue.h
#include "item.h"
typedef struct queue *queuePtr;
queuePtr newQueue();
int emptyQueue(queuePtr q);
item dequeue(queuePtr q);
int enqueue(item val, queuePtr q);
void checkPointer(queuePtr p);
queue.c
#include <stdlib.h>
#include <stdio.h>
#include "item.h"
#include "queue.h"
typedef struct node* nodePtr;
struct node{
item val;
nodePtr next;
};
struct queue{
nodePtr head, tail;
int dim;
};
queuePtr newQueue(){
queuePtr q = malloc(sizeof(struct queue));
if (q==NULL)
return NULL;
q->dim=0;
q->head=NULL;
q->tail=NULL;
return q;
}
int emptyQueue(queuePtr q){
if (q==NULL)
return -1;
return q->dim==0;
}
// aggiunge un nodo alla coda
int enqueue(item val, queuePtr q){
if (q==NULL)
return -1;
nodePtr nuovo = malloc(sizeof(struct node));
if (nuovo==NULL)
return 0;
nuovo->val=val;
nuovo->next=NULL;
if(q->head==NULL) {
q->head = nuovo;
}
else {
q->tail->next = nuovo;
}
q->tail=nuovo;
(q->dim)++;
return 1;
}
item dequeue(queuePtr q){
if (q==NULL)
return (item)NULL;
if (q->dim==0)
return (item)NULL;
item res = q->head->val;
struct node* tmt = q->head;
q->head=q->head->next;
free(tmt);
if (q->head==NULL)
q->tail=NULL;
(q->dim)--;
return res;
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include "queue.h"
int main() {
queuePtr q = newQueue();
item val = newItem(1);
item val2 = newItem(2);
enqueue(val, q);
enqueue(val2, q);
item ret = dequeue(q);
printf("x: %d\n", ret->x);
return 0;
}
But on compiling I have this error message:
/LibreriaQueque/main.c:17:26: error: dereferencing pointer to incomplete type ‘struct c_item’
printf("x: %d\n", ret->x);
The IDE gives me the same alert message in the queue.c but it works. I think that the problem is the item structure that is declared in the item.c and so it can't be seen in the main file and in the queue.c file. I can't move the structure declaration from item.c. How can I solve this problem?
You're doing an often sensible thing here: The struct is only defined in your implementation of the queue. This makes sure no other module can ever depend on the inner workings of your struct, so you can change it without touching any external code.
But in your main(), you try to do what you explicitly forbid: accessing the content of your struct. It's impossible because the compiler doesn't know the content when compiling your main file.
You have two options:
Move the definition of the struct to your header file, therefore making it public.
(IMHO preferred): Provide an accessor method like
int value(const item it)
{
return it->x;
}
and call that from your main code to get the value.
Side notes:
What is memory.h? I guess you don't need it
Better don't hide pointers behind typedef. You could to typedef struct c_item item; instead and use the explicit asterisk anywhere. It's easier to understand the code, C programmers expect pointers to be explicit.
You are close to using what's known as "opaque type" or "opaque pointers", which is a design pattern used for private encapsulation of ADTs. It works by declaring an incomplete struct in the header file, which the caller has access to. But only defining the struct in the c file, which the caller does not have access to. Therefore the caller can't know what's inside the struct, which is a good thing.
The downside of this method is that the caller can never create an instance of the object - only pointers to it. (It works pretty much like an abstract base class in C++.) So the caller has to rely on your "constructor" and "destructor" to do this.
Misc good practice:
There's a rule of thumb in C saying that you should never hide pointers behind typedefs, because doing so tends to confuse the reader.
When writing an ADT, it is good practice to prefix all functions, types and macros in the same way. In this case, I would name all functions queue_. Ideally you should have a coding standard stating how to prefix/postfix functions, macros and types belonging to an ADT.
You should never use empty parentheis for functions in C, because that's obsolete style and means "take any parameter". (Unlike in C++ where it means take no parameter.)
Use const correctness for the ADT function parameters.
Now to make your ADT opaque (which is good design), you need to do like this:
queue.h
typedef struct queue queue; // typedef of incomplete type
queue* queue_new (void);
void queue_delete (queue* q);
int queue_empty (const queue* q);
// and so on
queue.c
struct queue {
...
};
main.c
queue* q = queue_new();
I've started implementing a circular queue in C, and I have the following lines of code:
#include <stdio.h>
#include <stdlib.h>
#include "cirq.h"
//allocate a circular queue
cirq cq_alloc(void){
cirq cq = NULL;
element *head;
element *tail;
if((head = malloc(sizeof(struct element*))) &&
(tail = malloc(sizeof(struct element *)))){
head->content = 0; // head node keeps track of size.
tail->content = NULL;
head->next = tail;
tail->next = head;
cq = &head;
} else {
printf("ERROR: No space for more cqueues.\n");
}
return cq;
}
int cq_size(cirq q){
return (int)(*q)->content;
}
int main(){
cirq q = cq_alloc();
printf("Size of element ptr %lu\n", sizeof(struct element *));
printf("%d\n", cq_size(q));
return 0;
}
Now when I compile and run this program, having commented out the line in main that prints out sizeof(struct element *)), the program runs fine and I get the right size of the queue, 0. When I leave the line in, the size of the struct is printed out, but after that I get a segmentation fault: 11. Also, to make things clear, the struct element has void *data and struct element *next fields. How can adding in a line that prints stuff change the behavior of the program so much?
EDIT: cirq.h
#ifndef CIRQ_H
#define CIRQ_H
typedef struct element **cirq; // cirq handle
typedef struct element {
void *content;
struct element *next;
} element;
extern cirq cq_alloc(void);// allocate a queue
extern int cq_size(cirq q);// return the size of a queue
extern void cq_enq(cirq q, void *value);// add a value to the queue
extern void *cq_deq(cirq q);// dequeue and return a queue value
extern void *cq_peek(cirq q);// return the value at the queue head
extern void cq_rot(cirq q);// requeue the head element at the tail
extern void cq_free(cirq q);// return all space allocated to queue
#endif
This is a bad smell:
if((head = malloc(sizeof(struct element*))) &&
You're mallocing the size of a pointer. I think you meant to malloc the struct itself...?
It doesn't really matter what cirq is, the fact that you return the address of a local object is the problem.
This here
cq = &head;
is causing the undefined behavior, because that's the address of the pointer head which is stored locally in the function only, when the function returns it's deallocated and thus invalid. Using it elsewhere (outside the function) is Undefined Behavior.
Also, do not typedef a pointer. Never do that, let the code reader know that it is a pointer.
I am new to C. I have implemented a simple stack with some structs and what not. I have posted the entire code below. The problem section is commented.
#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
typedef struct Node{
int data;
struct Node *next;
} Node;
typedef struct Stack{
Node *top;
int size;
} Stack;
/* Function Prototypes */
void push(Stack *sPtr, int data);
int pop(Stack *sPtr);
void create(Stack *sPtr);
int main(void)
{
static Stack first;
create(&first);
push(&first,4);
push(&first,3);
push(&first,2);
printf("%d\n",pop(&first));
printf("%d\n",pop(&first));
printf("%d\n",pop(&first));
exit(1);
}
void push(Stack *sPtr, int data)
{
struct Node newNode;
newNode.data = data;
newNode.next = sPtr->top;
sPtr->top = &newNode;
sPtr->size++;
printf("%d\n",sPtr->top->data);
}
int pop(Stack *sPtr)
{
struct Node *returnNode = sPtr->top;
struct Node *topNode = sPtr->top;
if(sPtr->size != 0){
sPtr->top = topNode->next; /* =============PROBLEM?=============== */
return returnNode->data;
}
else{
printf("Error: Stack is Empty!\n");
return -1;
}
}
void create(Stack *sPtr)
{
sPtr->size = 0;
sPtr->top = NULL;
}
The output of this code is
4
3
2
2
8103136
680997
So obviously, it is pulling off the top node, and then printing the addresses of the next two nodes, instead of their data.
But why is it doing this? As far as I know (which is little) preforming this operation
sPtr->top = topNode->next;
should tell the program to make top now point to to topNode.next. But instead, it seems to be returning the address. What's going on here?
In your push() function, you're creating a new struct Node and adding it to your stack. However, the node is a local variable within the scope of push()--allocated on the stack (not your stack, the call stack), and will be gone when push() returns.
What you want to do is create the node on the heap, which means it will still be there after push() returns.
Since you're coding in C, you'll want to do something like:
struct Node *newNode = (struct Node*)malloc(sizeof(struct Node));
Since you're now dealing with heap-allocated memory, you'll need to make sure that at some point it gets freed (somewhere) using free().
You're also not decrementing size as Jonathan has pointed out.
One trouble is that pop() never decrements size, so size is really 'number of elements ever pushed onto stack', not 'the number of elements in the current stack'.
int pop(Stack *sPtr)
{
struct Node *returnNode = sPtr->top;
struct Node *topNode = sPtr->top;
if (sPtr->size != 0)
{
sPtr->top = topNode->next;
sPtr->size--;
return returnNode->data;
}
else
{
fprintf(stderr, "Error: Stack is Empty!\n");
return -1;
}
}
Another trouble, as pointed out by unluddite in his answer is that you are not pushing data correctly. You need both fixes to be safe. There might still be other problems (such as not freeing memory correctly — or at all), but these two will get you a long way.
I am trying to create a linked list in my program and I am not able to allocate memory to the structure pointer using malloc(). How do I allocate memory to variables in GCC? The sample program is given below. How to make it work in gcc?
#include<stdio.h>
#include <alloc.h>
struct node
{
int data;
struct node * link;
};
void insert (struct node *p, int d)
{
struct node *temp;
temp = malloc(sizeof(struct node));
temp->data=d;
temp->link=NULL;
if(p==NULL)
{
p=temp;
}
else{
while(p->link!=NULL)
p=p->link;
p->link=temp;
}
}
void disp(struct node *p)
{
while(p!=NULL)
{
printf("%d\n",p->data);
p=p->link;
}
}
int main()
{
struct node *p;
p=NULL;
insert(p,7);
insert(p,9);
disp(p);
}
The error I'm encountering is:
Line 18: error: alloc.h: No such file or directory
In function 'insert':
Line 13: warning: incompatible implicit declaration of built-in function 'malloc'
malloc is in <stdlib.h>. Include that.
Reading the man page for that function would have given you that information. It's not compiler-dependent.
malloc is declared in <stdlib.h>, so that's what you want to #include.
The definition of malloc is in the stdlib.h file:
#include <stdlib.h>
instead of alloc.h.
Like the others say: your error occurs because you have to include stdlib.h instead of alloc.h
To get your list printed, you have to modify p in insert. Currently, you're passing NULL every time you call insert. Change your code that way (pass a pointer-to-pointer to insert):
#include <stdio.h>
#include <stdlib.h>
struct node
{
int data;
struct node * link;
};
/* note **p instead of *p */
void insert (struct node **p, int d)
{
struct node *temp;
temp = malloc(sizeof(struct node));
temp->data=d;
temp->link=NULL;
if(*p==NULL)
{
*p=temp;
}
else{
while((*p)->link!=NULL)
*p=(*p)->link;
(*p)->link=temp;
}
}
void disp(struct node *p)
{
while(p!=NULL)
{
printf("%d\n",p->data);
p=p->link;
}
}
int main()
{
struct node *p;
p=NULL;
insert(&p,7);
insert(&p,9);
disp(p);
}
and it will print
7
9