If i enter 2 as input, the output is -572662307.
Can anyone figure out the problem?
struct node
{
int rollno;
struct node*n;
};
void read(struct node*);
void display(struct node*);
struct node* create();
struct node* cread();
struct node*head=NULL;
struct node*tail=NULL;
void read(struct node*p)
{
scanf("%d",&p->rollno);
p->n=NULL;
printf("\n");
}
void display(struct node*p)
{
printf("%d\n",p->rollno);
}
struct node* create()
{
struct node*q;
q=(struct node*)malloc(sizeof(struct node));
return q;
}
struct node* cread()
{
struct node*j;
j=create();
read(j);
return j;
}
void push(struct node*cur)
{
if(head==NULL)
{
head = cur;
tail = cur;
}
else
{
struct node*f;
f=head;
head->n = cur;
head=head->n;
}
}
struct node* pop()
{
struct node*p;
struct node*s = NULL;
p=tail;
if(p==NULL)
{printf("\n\t\t\tSTACK EMPTY\n");}
else
{
//display(p);
s = p;
tail=p->n;
free(p);
}
return s;
}
DWORD WINAPI workerThreadProcedure(LPVOID lparam)
{
struct node* cur;
struct node* disp = NULL;
printf("Enter the input: ");
cur =cread();
push(cur);
disp = pop();
printf("%d\n",disp->rollno);
return 0;
}
void main()
{
HANDLE workerThreadHandle[40];
int max_number=40;
for (int i = 0; i < 1; i++)
{
workerThreadHandle[i]= CreateThread( NULL,
0,
workerThreadProcedure,
(LPVOID)i,
0,
NULL
);
}
Sleep(5000);
}
I have to admit it's a bit difficult to follow but I think the problem is here:
struct node* pop()
{
struct node*p;
struct node*s = NULL;
p=tail;
if(p==NULL)
{printf("\n\t\t\tSTACK EMPTY\n");} // after that will jump to 'return' where 's' is NULL
else
{
//display(p);
s = p; // 's' and 'p' point to the same memory block now
tail=p->n;
free(p); // Ooops you've freed the memory block 's' and 'p' point to
}
return s; // You now return a freed memory block, this is undefined behavior
}
If it entered the if statement only, s will be returned NULL. In any case it's wrong.
You only free memory once you're done with it, keep track of what your pointers point to. Not sure what you wanted to do here, distinguish between the pointer and what it points to.
The pointer will expire at the end of the function, what it points to will not necessarily (especially if it's allocated with malloc).
It's entirely okay for several pointers to point to one thing and when you fiddle with that thing, it affects all pointers that point to it.
Related
I made a code in which malloc() is called, but it is returning a null pointer. When I call the same malloc() in main() and pass to the function, it is working totally fine. So please tell me what is the problem.
Here is my code. I am having problems with the malloc() in the function reverse(). The malloc()s in other functions are working fine. So why is there problem with the one in that function. I have enough memory in my computer, so that's definitely not the problem.
#include <stdio.h>
#include <stdlib.h>
typedef struct node
{
int data;
struct node *next;
} SNode;
typedef struct
{
int count;
SNode *top;
} Stack;
int isSEmpty(Stack *s)
{
return (s->count==0);
}
void push(Stack *s, int x)
{
SNode *temp = (SNode *)malloc(sizeof(SNode));
temp->data = x;
temp->next = s->top;
s->top = temp;
s->count++;
}
int pop(Stack *s)
{
if (isSEmpty(s))
{
printf("Underflow");
return -1;
}
SNode *temp = s->top;
s->top = s->top->next;
int t = temp->data;
free(temp);
s->count--;
return t;
}
typedef struct qnode
{
int data;
struct qnode *next, *prev;
} QNode;
typedef struct
{
QNode *front, *rear;
int count;
} Queue;
int isQEmpty(Queue *q)
{
return (q->count==0);
}
void enQueue(Queue *q, int x)
{
QNode *temp = (QNode *)malloc(sizeof(QNode));
temp->data = x;
temp->prev=q->rear;
temp->next = NULL;
q->rear->next = temp;
q->rear = temp;
q->count++;
if (q->count==1)
{
q->front = q->rear;
}
}
int deQueue(Queue *q)
{
if (isQEmpty(q))
{
printf("Underflow");
return -1;
}
QNode *temp = q->front;
q->front = q->front->next;
int t = temp->data;
free(temp);
q->count--;
return t;
}
void reverse(Queue *q)
{
Stack *s = (Stack *)malloc(sizeof(Stack));
s->count = 0;
while (!isQEmpty(q))
{
push(s, deQueue(q));
}
while (!isSEmpty(s))
{
enQueue(q, pop(s));
}
}
int main()
{
char p = 'y';
Queue *q = (Queue *)malloc(sizeof(Queue));
q->count = 0;
while (p =='y')
{
printf("Enter data to be Enqueued: ");
int d;
scanf("%d", &d);
enQueue(q, d);
printf("Do you want to enter more data? y/n:");
scanf(" %c", &p);
}
printf("Original queue Front: %d Rear: %d\n", q->front->data, q->rear->data);
reverse(q);
printf("Reversed queue Front: %d Rear: %d", q->front->data, q->rear->data);
return 0;
}
Your program is hardly running out of memory, which is why malloc() would return NULL. Instead a combination of bad programming style and messy code, is causing problems related to access of uninitialized memory which is undefined behavior, once you trigger the UB you can't predict program's behavior anymore.
The first thing you need to fix, is avoiding this kind of construction
q->rear->next = temp;
because q->rear might be NULL and thus you would invoke UB if you dereference it.
Then you need to initialize the members of the struct explicitly, malloc() only allocates memory for you to use, it does no initialization whatsoever, a good method to do it would be to create a function that allocates and initializes empty instances, like the following
Queue *queue_new(int count)
{
Queue *queue;
queue = malloc(sizeof(*queue));
if (queue == NULL)
return NULL;
queue->count = count;
queue->front = NULL;
queue->rear = NULL;
return queue;
}
Also, don't mix declarations with code. I had to search for the definition of Queue to write the above function, and I did so with the find/replace feature of my code editor.
Place all structure and type definitions together above all the code, to make it easy to find any one of them.
You aren't initializing all the fields of the *q struct that you initiallay allocate in `main():
Queue *q = (Queue *)malloc(sizeof(Queue));
q->count = 0;
Then you pass that q pointer to enQueue() and do things like:
q->rear->next = temp;
I think you may also use q->front without having initialized it.
These things are undefined behavior and in your case are probably corrupting the heap causing malloc() to not work as you expect. If you're working on Linux valgrind might be useful.
I am trying to implement a stack using linked list. Here is my code:
#include<stdio.h>
//implementation of stack
struct Node{
int data;
struct Node* next;
struct Node* prev;
};
struct Stack{
struct Node* headNode;
struct Node* presentNode;
int size;
};
struct Node* newNode()
{
struct Node* node;
return node;
}
struct Stack* newStack()
{
struct Stack* stack;
stack->headNode = newNode();
stack->presentNode = stack->headNode;
stack->size=0;
return stack;
}
int isempty(struct Stack* s)
{
if(s->headNode->next != NULL)
return 0;
return 1;
}
void push(struct Stack* s,int data)
{
struct Node* node = newNode();
node->data = data;
node->next = NULL;
s->presentNode->next = node;
node->prev = s->presentNode;
s->presentNode = node;
s->size ++;
}
int pop(struct Stack*s)
{
if(isempty(s)==1)
return 0;
int data = s->presentNode->data;
s->presentNode->prev->next = NULL;
s->presentNode = s->presentNode->prev;
s->size --;
return data;
}
int main()
{
struct Stack* stack = newStack();
int data = 0,type;
printf("Enter '1' if new element to be added or '0' if the latest element is to be deleted.\n");
while(data!=-1)//unbounded stack
//takes input until data==-1
{
scanf("%d",&type);
if(type)
{
printf("Enter the element:\t");
scanf("%d",&data);
if(data==-1)
continue;
push(stack,data);
}
else
printf("%d is popped out of the list!\n",pop(stack));
}
return 0;
}
But I am getting run-time error. Since I am new to pointers (I am a Java guy), I am pretty confused where my error is, although I am sure it is due to pointers.
You do not allocate memory for your new nodes:
struct Node* newNode()
{
struct Node* node;
return node;
}
Local variable node is an uninitialized pointer. As soon as you use the return value of this function, you have Undefined Behaviour.
Edit:
The same problem is true for newStack:
struct Stack* newStack()
{
struct Stack* stack;
stack->headNode = newNode();
...
return stack;
}
As soon as you dereference stack, you have Undefined Behaviour.
You have multiple problems. For starters
In your newStack() function, you do not have a return statement, so using the return value causes undefined behavior.
You need to allocate memory to pointers (i.e., make pointers to point to valid memory) before you can actually dereference them. In your case
struct Stack* stack;
stack->headNode
is an attempt to use uninitialized memory which again causes UB.
I am having trouble implementing a function that deletes the first element from a stack. (I know for sure that the stack has minimum two elements)
typedef struct Node {
T value;
struct Node *next;
} Node;
typedef struct Stack {
Node *head;
} Stack;
void Pop(Stack **st) {
if (!IsEmptyStack(*st)) {
Node* aux = (*st)->head;
(*st)->head = (*st)->head->next;
}
}
but same happens... Segmentation fault.
How can I fix the pop function?
Here are the other functions i'm using:
void InitStack(Stack **st)
{
(*st) = (Stack *) malloc(sizeof(Stack *));
(*st)->head = NULL;
}
int IsEmptyStack (Stack *st)
{
if (!st)
return 1;
else
return 0;
}
The first approach seems correct, but why do you pass a double pointer to the Stack to function Pop? It seems Pop could be simplified this way:
typedef struct Node {
T value;
struct Node *next;
} Node;
typedef struct Stack {
Node *head;
} Stack;
void Pop(Stack *st) {
if (!IsEmptyStack(st)) {
Node *aux = st->head;
st->head = aux->next;
... // dispose of aux appropriately
}
}
IsEmptyStack was wrong..
instead of
int IsEmptyStack (Stack *st)
{
if (!st)
return 1;
else
return 0;
}
I have to use
int IsEmptyStack (Stack *st)
{
if (!st->head)
return 1;
else
return 0;
}
That's because i've already allocated memory for st .. so checking st is irrelevant.
Method:
Traverse the given list from head to tail and push every visited node to stack.
Traverse the list again. For every visited node, pop a node from stack and compare data of popped node with currently visited node.
If all nodes matched, then return true, else false.
Edit: The program compiles without an error but stops working during run time
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <stdbool.h>
struct Node
{
int data;
struct Node *next;
};
struct Stack
{
unsigned capacity;
int top;
int * array;
};
struct Stack* createStack(unsigned capacity)
{
struct Stack* stack=(struct Stack*)malloc(sizeof(struct Stack));
stack->capacity=capacity;
stack->top=-1;
stack->array=(int *)malloc(sizeof(int)*stack->capacity);
return stack;
}
int isFull(struct Stack* stack)
{ return stack->top == stack->capacity - 1; }
// Stack
int isEmpty(struct Stack* stack)
{ return stack->top == -1; }
// stack.
void push(struct Stack* stack, int item)
{
if (isFull(stack))
return;
stack->array[++stack->top] = item;
printf("%d pushed to stack\n", item);
}
// stack.
int pop(struct Stack* stack)
{
if (isEmpty(stack))
return INT_MIN;
return stack->array[stack->top--];
}
// stack
int peek(struct Stack* stack)
{
if (isEmpty(stack))
return INT_MIN;
return stack->array[stack->top];
}
// linkedlist
void insert(struct Node** head_ref, int new_data)
{
struct Node* new_node =
(struct Node*) malloc(sizeof(struct Node));
new_node->data = new_data;
new_node->next = (*head_ref);
(*head_ref) = new_node;
}
bool compare(struct Stack* stack,struct Node* head)
{
struct Node* temp,* curr=head;
while(temp)
{
push(stack,temp->data);
temp=temp->next;
}
while(curr)
{
if(pop(stack)==curr->data)
{
curr=curr->next;
}
else
exit(0);
}
return true;
}
// Driver program to test above functions
int main()
{
struct Stack* stack = createStack(100);
struct Node* head=NULL;
insert(&head,1);
insert(&head,2);
insert(&head,1);
printf("%s",compare(stack,head));
return 0;
}
Function compare has at least two errors. The first one is that it uses uninitialized pointer temp
bool compare(struct Stack* stack,struct Node* head)
{
struct Node* temp,* curr=head;
while(temp) // <= temp is not initialized
{
The second one is that the function never returns false though according to the assignment it has to return false if values in the list and in the stack do not match.
Instead of returning false you call function exit
else
exit(0);
I would write the function the following way
bool compare(struct Stack *stack, struct Node *head )
{
struct Node *current = head;
for ( ; current != NULL && !isFull( stack ); current = current->next )
{
push( stack, current->data );
}
current = head;
while ( current != NULL && !isEmpty( stack ) && pop( stack ) == current->data )
{
current = current->next;
}
return current == NULL && isEmpty( stack );
}
It is the only correct function implementation among presented here function implementations in other answers.:)
As C does not have type bool then that you could use name bool in a program written in C you have to include header <stdbool.h> or define this name yourself as a typedef either of _Bool (if your compiler supports this type) or of int.
You could declare the return type of the function as int if you do not want to include header <stdbool.h>. For example
int compare(struct Stack *stack, struct Node *head );
Take into account that you need to write also functions that will free all allocated memory for the list and the stack.
For example you could free memory allocated for the stack the following way
void freeStack( struct Stack **stack )
{
if ( *stack != NULL ) free( ( *stack )->array );
free( *stack );
*stack = NULL;
}
The same way you could free the memory allocated for the list
void freeList( struct Node **head )
{
if ( *head != NULL )
{
Node *current = ( *head )->next;
while ( current != NULL )
{
Node *temp = current;
current = current->next;
free( temp );
}
}
free( *head );
*head = NULL;
}
struct Node* temp;
temp is not initialized in
bool compare(struct Stack* stack,struct Node* head)
struct Node* temp,* curr=head;
is not
struct struct Node* temp=head,* curr=head;
Using uninitialized variables lead to undefined behavior.
You've got an uninitialized local variable temp:
bool compare(struct Stack* stack,struct Node* head)
{
struct Node* temp,* curr=head;
while(temp) // NOT INITIALIZED
{
push(stack,temp->data);
temp=temp->next;
}
while(curr)
{
if(pop(stack)==curr->data)
{
curr=curr->next;
}
else
exit(0);
}
return true;
}
You need to fix that first; I think the following should work:
bool compare(struct Stack* stack,struct Node* head)
{
struct Node *curr;
for (curr = head; curr != NULL; curr = curr->next)
{
push(stack, curr->data);
}
for (curr = head; curr != NULL; curr = curr->next)
{
if (pop(stack) != curr->data)
return false;
}
return true;
}
Next, you're printing a boolean result with "%s", which is for strings. You need to do something like:
c=compare(stack,head);
printf("%d\n", c);
or alternatively
printf("%s\n", c ? "true" : "false");
At this point, it no longer crashes for me, and works for a couple simple test cases. You might think about how to handle the case of overflowing the stack, and also consider formatting your code to make it more readable.
bool compare(struct Stack* stack,struct Node* head) {
struct Node* temp=head;//<- Needs initialising. It wasn't.
struct Node* curr=head;
while(temp) {
push(stack,temp->data);
temp=temp->next;
}
while(curr) {
if(pop(stack)==curr->data) {
curr=curr->next;
} else {
//exit(0); <--Some mistake surely!
return false; //Slightly less drastic!
}
}
return true;
}
It's slightly a matter of taste but I find long series of variable declarations to be difficult to read and hence error-prone.
You only really need one local variable - but your compiler probably optimizes that away.
exit(0) will abruptly end the program. Most likely indicates 'success' (the exit of 0).
You should return false;.
PS: Credit for using #include <stdbool.h>.
I am having trouble with inserting items in linked list. All the elements end up having the same *data content that is inserted in the last. The program compiles successfully. I use gcc and gdb.
I am new to coding so please mention troubles if any that you see in my programming style.
typedef struct Node{
void* data;
struct Node* next;
} *node;
node allocate(){
node current = malloc(sizeof(struct Node));
current->data = NULL;
current->next = NULL;
return current;
}
void insert(node *head, void *data){
// if head has no data then set the data on head and return
if(((*head)->data == NULL)&&((*head)->next == NULL)){
(*head)->data = data;
return;
}
node newHead = allocate();
newHead->data = data;
newHead->next = *head;
*head = newHead;
//printf("Node Data : %d\tNext Node Data : %d",
//*(int *)((*head)->data), *(int *)((*head)->data));
}
int main(int argc, char *argv[]){
node head = allocate();
int count = inputSequence(&head);
int *aod = calloc((size_t) count, sizeof(int));
generateAOD(head, aod);
if(checkJolly(aod, count) == TRUE)
printf("Jolly\n");
else
printf("Not Jolly\n");
return 0;
}
int inputSequence(node *input){
int *num = malloc(sizeof(int));
int count = 0;
while((scanf("%d", num) != EOF)){
insert(input, (void *)num);
count++;
}
traverse(*input, fn);
return count;
}
Your insert logic is non-existant. And you're literally making your life harder by attempting to manage a linked list in the fashion you're using.
The head pointer itself should indicate whether the list is empty. If it is NULL, its empty. If it isn't, there's data. Code the insertion logic accordingly.
And your inputSequence is utterly broken. It only allocates ONE data point, then uses the same data allocation for every insertion. You need one for each insertion.
First, change allocate() to accept the data being inserted. It will make the remaining code less cluttered:
node allocate(void *data)
{
node current = malloc(sizeof(*current));
current->data = data;
current->next = NULL;
return current;
}
Second, insert by allocating a new node as needed.
void insert(node *head, void *data)
{
node p = allocate(data);
p->next = *head;
*head = p;
}
Next, fix inputSequence() to properly allocate memory for each entry:
int inputSequence(node *input)
{
int count = 0;
int num = 0;
// note: check for number of params *successfully* parsed.
// if it isn't 1, its time to leave the loop.
while(scanf("%d", &num) == 1)
{
int *data = malloc(sizeof(num));
*data = num;
insert(input, data);
++count;
}
return count;
}
And lastly, make sure your head pointer is initially NULL in main().
int main(int argc, char *argv[])
{
node head = NULL;
// load linked list
inputSequence(&head);
// ... the rest of your code....;
return 0;
}
With the above, the logical answer of "Is my list empty" is simply if (!head) Further, this makes things like traversal trivial.
void traverse(node ptr, void (*pfn)(void *))
{
while (ptr)
{
pfn(ptr->data);
ptr = ptr->next;
}
}
Freeing the list is equally trivial:
void destroy(node *head)
{
while (*head)
{
node p = *head;
*head = p->next;
free(p->data);
free(p);
}
}
typedef struct Node{
void* data; // Make it as int or any other data type
struct Node* next;
} *node;
In function inputSequence() you are allocating memory for num at the very beginning and making node->data point to this memory each time you are adding a node. Hence data pointer of each node of your linked list points to the same memory location and hence contains the same value.
If you still want to continue with data as a void pointer, allocate num for each iteration of the while loop and pass this to insert function.
while((scanf("%d", num) != EOF)){
num = malloc(sizeof(int);
insert(input, (void *)num);
count++;
}