I'm trying to build a stack using a linked list but I get a EXC_BAD_ACCESS error in my linkedListStackInit method;
LinkedList.h
#ifndef LinkedListStack_h
#define LinkedListStack_h
#ifndef __TYPE
#define __TYPE
#define TYPE int
#define TYPE_SIZE sizeof(int)
#endif
#include <stdio.h>
struct Link;
struct LinkedListStack;
void linkedListStackInit(struct LinkedListStack *s);
void push(struct LinkedListStack *s, TYPE data);
void pop(struct LinkedListStack *s);
TYPE top(struct LinkedListStack *s);
int isEmpty(struct LinkedListStack *s);
#endif
LinkedList.c
#include <stdlib.h>
#include "LinkedListStack.h"
struct Link {
TYPE value;
struct Link *next;
};
struct LinkedListStack {
struct Link *firstLink;
};
void linkedListStackInit(struct LinkedListStack *s) {
s->firstLink = 0;
}
void push(struct LinkedListStack *s, TYPE data) {
struct Link *newLink = malloc(sizeof(struct Link));
// Assert?
newLink->next = s->firstLink;
newLink->value = data;
s->firstLink = newLink;
}
void pop(struct LinkedListStack *s) {
struct Link *temp = s->firstLink;
s->firstLink = s->firstLink->next;
free(temp);
}
TYPE top(struct LinkedListStack *s) {
return s->firstLink->value;
}
int isEmpty(struct LinkedListStack *s) {
if(s == NULL) {
return 0;
}
else {
return 1;
}
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include "LinkedListStack.h"
int main(int argc, const char * argv[]) {
struct LinkedListStack *s;
linkedListStackInit(s);
return 0;
}
From your main method you are calling the function linkedListStackInit and passing stack (s) to it. But you haven't allocated memory to s before passing it to the linkedListStackInit function. The function linkedListStackInit doesn't allocate the memory either and tries to assign a value to its "firstlink" member. Try to do the following in your linkedListStackInit function and see if you can proceed further.
s = malloc(sizeof(struct LinkedListStack));
Related
I'm trying to use a Queue as a buffer for failed messages via LTE-M. So that if there is a connection again i can send all the failed messages out of the buffer.
For that i created two files.
queue_array.h
#ifndef INC_QUEUE_ARRAY_H_
#define INC_QUEUE_ARRAY_H_
#include <stdint.h>
#include <stdlib.h>
#include <stdbool.h>
#define QUEUE_EMPTY 0
/*Queue has five properties. capacity stands for the maximum number of elements Queue can hold.
Size stands for the current size of the Queue and elements is the array of elements. front is the
index of first element (the index at which we remove the element) and rear is the index of last element
(the index at which we insert the element) */
typedef struct
{
int head, tail, num_entries, size;
char **values;
}queue;
void init_queue(queue *q, int max_size);
bool queue_empty(queue *q);
bool queue_full(queue *q);
void queue_destroy(queue *q);
bool enqueue(queue *q , char *element);
int dequeue(queue *q);
int count_queue(queue *q);
char* front(queue *q);
#endif /* INC_QUEUE_ARRAY_H_ */
Queue_array.c
#include "queue_array.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
void init_queue(queue *q, int max_size)
{
q->size=max_size;
q->values=(char**)malloc(sizeof(char*)*q->size);
q->num_entries =0; //empty
q->head=0;
q->tail=0;
}
bool queue_empty(queue*q)
{
return(q->num_entries ==0);
}
bool queue_full(queue*q)
{
return(q->num_entries == q->size);
}
void queue_destroy(queue*q)
{
free(q->values);
}
int dequeue(queue *q)
{
if(queue_empty(q))
{
return QUEUE_EMPTY;
}
q->head = (q->head +1) % q->size;
q->num_entries--;
return 1;
}
char* front(queue *q)
{
if(q->size!=0)
{
/* Return the element which is at the front*/
return q->values[q->head];
}
return NULL;
}
int count_queue(queue *q)
{
return q->num_entries;
}
bool enqueue(queue *q , char *element)
{
if(queue_full(q))
{
return false;
}
else
{
q->num_entries++;
q->tail=(q->tail +1) % q->size;
q->values[q->tail] = (char *) malloc((sizeof(element)+1)* sizeof(char));
strcpy(q->values[q->tail], element);
}
return true;
}
Now when i run this code i only have these chars in the front element: "MESSAGE". Because there is something of the message there i think the mistake is in the enqueue function where the storage of the q->value is allocated.. But i dont know where. Does someone see the mistake?
Run Code:
char *temp;
init_queue(&msg_queue, 5);
if(enqueue(&msg_queue,"FIRSTFAILEDTEXTMESSAGE")!=0)
{
//nothing
}
if(enqueue(&msg_queue,"SECONDFAILEDTEXTMESSAGE")!=0)
{
//nothing
}
temp= front(&msg_queue);
temp = (char *)malloc(22 * sizeof(char )); //allocate the first message with 22 Chars
why i am getting stack is empty every time?
I am trying to make a expression tree from postfix here.
what's the logical error here?? plus we are not allowed to declare any variable globally. so, i had to pass the stackarray and node every time in each time function calling.
i am posting the full code done by me please have a look, i know its might be a simple error but as a beginner please show some kindness.
please help. TIA :)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAXSIZE 10
struct ExpnTreeNode
{
struct ExpnTreeNode *lchild;
char data;
struct ExpnTreeNode *rchild;
};
struct stackarray
{
struct ExpnTreeNode *data[MAXSIZE];
int top;
};
void push(struct ExpnTreeNode *newnode, struct stackarray *s);
struct ExpnTreeNode* pop( struct stackarray *s);
int check(char c);
void operand(struct ExpnTreeNode *newnode,char m, struct stackarray *s);
void operators(struct ExpnTreeNode *newnode,char m, struct stackarray *s);
void printex(struct ExpnTreeNode *node);
int main(void)
{
struct ExpnTreeNode *p=NULL;
struct stackarray s={{NULL},-1} ;
int len;
int x;
int res;
int i;
char arr[30]={'\0'};
printf("\n\tEnter a postfix expression:");
scanf("%d",&arr);
struct ExpnTreeNode *newnode=NULL;
len=strlen(arr);
for(i=0;arr[i]!='\0';i++)
{
x=check(arr[i]);
if(x==1)
{
operand(newnode,arr[i],&s);
}
else if(x==2)
{
operators(newnode,arr[i],&s);
}
}
p=pop(&s);
printex(p);
return 0;
}
void push(struct ExpnTreeNode *newnode, struct stackarray *s)
{
if(s->top==MAXSIZE-1)
{
printf("\n\tStack is Full");//Stack is Full
}
else
{
s->top=s->top+1;
s->data[s->top]=newnode;
}
}
struct ExpnTreeNode* pop( struct stackarray *s)
{
if(s->top==-1)
{
printf("\n\tStack is Empty");
return;
}
s->top=s->top-1;
return(s->data[s->top]);
}
int check(char c)
{
if(c=='*' || c=='/' || c=='+' || c=='-')
{
return 2;
}
else
{
return 1;
}
}
void operand(struct ExpnTreeNode *newnode,char m, struct stackarray *s)
{
struct stack *fs=NULL;
fs=s;
newnode=(struct ExpnTreeNode *)calloc(1,sizeof(struct ExpnTreeNode));
newnode->data=m;
newnode->lchild=NULL;
newnode->rchild=NULL;
push(newnode,&fs);
}
void operators(struct ExpnTreeNode *newnode,char m, struct stackarray *s)
{
newnode=(struct ExpnTreeNode *)calloc(1,sizeof(struct ExpnTreeNode));
struct stack *fs=NULL;
fs=s;
newnode->data=m;
newnode->rchild=pop(&fs);
newnode->lchild=pop(&fs);
push(newnode,&fs);
}
void printex(struct ExpnTreeNode *node)
{
if(node!=NULL)
{
printf("\n\t%c",node->data);
printex(node->lchild);
printex(node->rchild);
}
}
So I'm trying to implement a linked list stack that takes in char arguments and adds them to the link list with it's ascii code as the value of the nodes.
I pass in my nstack pointer into my push function and re-assign it to new_node in order to create a new top, but my push function doesn't seem to be reassigning my nstack node - it just prints the originally initialized nstack value. Why isn't nstack being reassigned?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct list_node {
int element;
struct list_node * pnext;
};
void push(struct list_node *operators, int e);
int pop(struct list_node *operators);
int main(int argc, char *argv[]) {
int newvalue = (int)argv[1][0];
struct list_node * nstack = (struct list_node*)malloc(sizeof(struct list_node));
nstack->element = newvalue;
nstack->pnext = NULL;
int i;
for (i = 2; i < argc; i++) {
push(nstack, (int)argv[i][0]);
}
printf("top: %d\n", nstack->element);
}
void push(struct list_node *nstack, int e) {
struct list_node * new_node = (struct list_node*)malloc(sizeof(struct list_node));
new_node->pnext = nstack;
new_node->element = e;
nstack = new_node;
}
Because you are passing a copy of pointer (by value). You need something like this (pointer to pointer):
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct list_node {
int element;
struct list_node * pnext;
};
void push(struct list_node **operators, int e);
int pop(struct list_node *operators);
int main(int argc, char *argv[]) {
//int newvalue = (int)argv[1][0];
int newvalue = 1;
struct list_node * nstack = (struct list_node*)malloc(sizeof(struct list_node));
nstack->element = newvalue;
nstack->pnext = NULL;
int i;
for (i = 2; i < 7; i++) {
//push(nstack, (int)argv[i][0]);
push(&nstack, i);
}
printf("top: %d\n", nstack->element);
}
void push(struct list_node **nstack, int e) {
struct list_node * new_node = (struct list_node*)malloc(sizeof(struct list_node));
new_node->pnext = *nstack;
new_node->element = e;
*nstack = new_node;
}
To expand on Tarod's correct point. What the caller function is doing is taking a copy of your pointer value and putting it onto the stack or in a register (compiler dependent) that will then be used in your push function. However, within your push function you're actually changing the value in this register or stack location before returning. But when you return the caller function basically discards this information (its popped of the stack - or, again depending on the compiler, uses the register for something else). The only way around this is to pass the address of the pointer and deference this when you need to write to it as Tarod has shown.
This code is about binary tree.
It can work well.
But after I press the enter key and get the correct answer,it turns out stopping working.WHY?
This is the answer
source code:
#include <stdio.h>
#include <stdlib.h>
typedef struct BiTNode
{
char data;
struct BiTNode* rchild;
struct BiTNode* lchild;
}BiTNode;
typedef BiTNode* BiTree;
int CreateBiTree(BiTree *T);
void Visit(BiTree T);
void PreOrder(BiTree T);
void InOrder(BiTree T);
void PostOrder(BiTree T);
int main(void)
{
BiTree T;
CreateBiTree(&T);
PreOrder(T);
return 0;
}
int CreateBiTree(BiTree *T)
{
char data;
scanf("%c",&data);
if(data=='#')
{
*T==NULL;
}
else
{
*T=(BiTree)malloc(sizeof(BiTNode));
(*T)->data=data;
CreateBiTree(&(*T)->lchild);
CreateBiTree(&(*T)->rchild);
}
return 0;
}
void Visit(BiTree T)
{
printf("%c",T);
}
void PreOrder(BiTree T)
{
if(T!=NULL)
{
Visit(T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
In your Code you have many issues :-
In CreateBiTree(BiTree *T) function, you only modified single pointer for root, rchild and lchild. you should define Bitree *T locally in this function.
what is *T==NULL? Are you initializing or comparing?
scanf("%c",&data); this statement will also create a problem in character case. this statement will wait for '\n' also. so you should write scanf(" %c",&data).
*T=(BiTree)malloc(sizeof(BiTNode)); this statement is also wrong, malloc return pointer, so you should do correct type casting. *T=(BiTree *)malloc(sizeof(BiTNode));
i have modified you source code for your reference, have look
//it can work
#include<stdio.h>
#include<stdlib.h>
using namespace std;
typedef struct BiTNode
{
char data;
struct BiTNode* rchild;
struct BiTNode* lchild;
}BiTNode;
typedef BiTNode BiTree;
BiTree *CreateBiTree();
void Visit(BiTree **T);
void PreOrder(BiTree *T);
void InOrder(BiTree T);
void PostOrder(BiTree T);
int main(void)
{
BiTree *T;
T=CreateBiTree();
PreOrder(T);
return 0;
}
BiTree *CreateBiTree()
{
BiTree *T;
char data;
scanf(" %c",&data);
printf("............%c\n",data);
if(data=='#')
return NULL;
T=(BiTree *)malloc(sizeof(BiTree));
T->data=data;
printf("Enter left child of %c:\n",data);
T->lchild=CreateBiTree();
printf("Enter right child of %c:\n",data);
T->rchild=CreateBiTree();
return T;
}
void Visit(BiTree **T)
{
printf("%c",(*T)->data);
}
void PreOrder(BiTree *T)
{
if(T!=NULL)
{
Visit(&T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
i am trying to implement a stack by writing all its functions in a separate source file.but i get a lot of errors saying incompatible pointer type.these errors don't show up when i include the functions in the main C file.these are my files.i am new to this.help me correct them.
thank you.
my main code is
#include "myfunctions.h"
int main()
{
int operation,data;
struct stack *One = (struct stack *)malloc(sizeof(struct stack));
One->top = -1;
printf("stack functionality \n");
while(1)
{
if (isEmpty(One))
{
printf("enter 1 to push \n");
scanf("%d",&operation);
}
else if (isFull(One))
{
printf("stack is full.enter 2 to pop or 3 to diplay \n");
scanf("%d",&operation);
}
else
{
printf("enter 1 to push,2 to pop,3 to display 4 to exit \n");
scanf("%d",&operation);
}
switch (operation)
{
case 1: printf("enter data to be pushed \n");
scanf("%d",&data);
push(One,data);
break;
case 2: printf("%d \n",pop(One));
break;
case 3: display(One);
break;
case 4:exit(0);
}
}
}
stackfns code
#include <myfunctions.h>
bool isEmpty(struct stack *b)
{
if(b->top == -1) return true;
else return false;
}
bool isFull(struct stack *b)
{
if(b->top == 9) return true;
else return false;
}
void push(struct stack *b,int data)
{
b->a[++(b->top)] = data;
}
int pop(struct stack *b)
{
return (b->a[(b->top)--]);
}
void display(struct stack *b)
{
int i;
for (i=0;i<10;i++)
printf("%d ",b->a[i]);
printf("\n");
}
header file
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
extern bool isEmpty(struct stack *b);
extern bool isFull(struct stack *b);
extern void push(struct stack *b,int data);
extern int pop(struct stack *b);
extern void display(struct stack *b);
#define max_size 10
struct stack
{
int a[max_size];
int top;
};
In the header file you need to first decalre the struct:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define max_size 10
struct stack
{
int a[max_size];
int top;
};
extern bool isEmpty(struct stack *b);
extern bool isFull(struct stack *b);
extern void push(struct stack *b,int data);
extern int pop(struct stack *b);
extern void display(struct stack *b);
In addition, there is no need to expose the internal implementation of the data structure. You can do something like:
.h file:
typedef struct xx_t xx_t;
.c file:
struct xx_t {
...
};