Pass by reference for structure in C - c

I want to pass a node by reference to a function and expect the variable in main() to be updated by the function
struct stack
{
int item;
struct stack *link;
};
void push(int item, struct stack *top)
{
/* allocate memory and insert item*/
}
int main(void)
{
struct stack *top;
push(10,top);
printf("%d\n",top->item);
return 0;
}
Here it displays 'segmentation fault', as if top did not get updated at all!

You need to pass the pointer top in main() by reference to the function push(). So give the address of top not its value.
So use
push(10,&top);
instead of
push(10,top);
if the changes made to top in push() are to reflected back in main().
This necessitates the modification of the function prototype. Use
void push(int item,struct stack **top)
instead of
void push(int item,struct stack *top)
And use *top in places where you used top in the push().

There are two options for what you need to do, depending on whether your function allocates the stack or the main() function allocates the stack element.
Option 1 — main() allocates top
void push(int item, struct stack *top)
{
top->link = 0;
top->item = item;
}
int main(void)
{
struct stack top; // Plain structure, not a pointer
push(10, &top); // Pass address of structure to function
printf("%d\n", top.item);
return 0;
}
This doesn't work particularly well in the context of a stack, but can often be the correct way to process structures — the calling code allocates the structure and the called code uses the allocated structure. Here is a dynamic allocation in the calling code, passed to the function to be initialized:
int main(void)
{
struct stack *top = malloc(sizeof(*top));
if (top != 0)
{
push(10, top);
printf("%d\n", top->item);
free(top);
}
return 0;
}
Option 2 — push() allocates top
void push(int item, struct stack **top)
{
struct stack *node = malloc(sizeof(*node));
node->link = *top;
node->item = item;
*top = node;
}
int main(void)
{
struct stack *top = 0; // Initialization is crucial
push(10, &top);
printf("%d\n", top->item);
push(20, &top);
printf("%d %d\n", top->item, top->link->item);
free(top->link);
free(top);
return 0;
}
This code is weird because it uses fixed operations instead of loops, but is otherwise kosher. All the code shown using malloc() has been tested with Valgrind and gets a clean bill of health.

Related

Reversing a stack using queue in C

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.

Destructor and constructor in C

I'm very new to C and I'm trying yet to fully understand it. I implemented a stack
but found trouble when making its destructor and it constructor/init.
Are these well done?
These are the typedefs for the structures used by the stack:
typedef struct Node{
void* cargo;
struct Node* next;
}Node;
typedef struct Stack{
int size;
Node* firstOut;
}Stack;
And these are the functions:
void newStack(Stack* stack){
stack = (Stack*)malloc(sizeof(Stack));
stack->firstOut = NULL;
stack->size = 0;
}
void freeStack(Stack** stack){
empty((*stack));
free((*stack)->top);
(*stack)->size = 0;
free(stack);
}
My question is: are they well done? How would someone with proper experience do it?
newStack should simply return the stack pointer that it allocates. It doesn't need to receive a Stack* as an argument.
stack *newStack() {
Stack *stack = malloc(sizeof(Stack));
if (stack != NULL) { // allocation successful
stack->firstOut = NULL;
stack->size = 0;
}
return stack;
}
and freeStack should receive a stack pointer as argument, it doesn't need double indirection.
void freeStack(Stack *stack) {
empty(stack);
free(stack->firstOut); // This isn't done by empty()?
free(stack);
}
There's no need to set stack->size before freeing, since the memory is going to go away and the value it contains is irrelevant.

Implementing a linked list with a stack in C

For a prelab (meaning it's not for a grade), I'm supposed to implement my first ever stack using linked lists. I wrote it adding only one thing to the stack just as practice, as to why it's so short. Anyway, I have no compile errors, besides it saying that "new" is uninitialized in my create_stack function. This is also where I'm getting a segmentation fault, as it's not printing out my first printf function. I am also guessing that the problem is bigger than just me initializing the stack, but this is my problem's start. Please go easy on me if it's something simple, as, like I said, it's my first time doing stacks, and thanks for your help.
#include <stdio.h>
#include <stdlib.h>
typedef struct node_{
char data;
struct node_ *next;
}node;
typedef struct stack_{
unsigned int size;
node* stack;
}stack;
stack* create_stack();
void push(stack* s, char val);
char top(stack* s);
void pop(stack*s);
int main(void) {
char value, val;
stack* new = create_stack();
printf("Enter a letter: ");
scanf("%c", &value);
push(new, value);
val = top(new);
printf("%c\n", val);
pop(new);
return 0;
}
stack* create_stack(){ //initializes the stack
stack* new;
new->size = 0;
new->stack = NULL;
return new;
}
void push(stack* s, char val) {
node* temp = (node*)malloc(sizeof(node)); //allocates
if ( temp == NULL ) {
printf("Unable to allocate memory\n");
}
else{
temp->next = s->stack;
temp->data = val;
s->stack = temp;
s->size = (s->size) + 1; //bumps the counter for how many elements are in the stack
}
}
void pop(stack* s) {
node* temp;
temp = s->stack;
s->stack = temp->next;
free(temp);
s->size = (s->size) - 1; //subtracts from counter
}
char top(stack* s) {
node* temp = s->stack;
char value = temp->data;
return value;
}
The reason it crashes is that you never allocate any memory when you create the stack. Do stack* new = malloc (sizeof(stack)); in the create_stack function.
For the future you might want to use better variable names. Using for instance using new as the name for the stack isn't that good - it isn't very descriptive plus it's a reserved keyword in several languages, C++ for example.
stack *new creates a local pointer, but it has nothing to point to yet. Since you want the stack to continue to exist after the function completes, you should allocate memory for it using malloc (and eventually free it using free).
So your create_stack function should start with:
stack* new = malloc(sizeof(stack));
An alternative would be to declare the stack as a local variable in your main function, and pass it as an argument into create_stack to initialize it:
stack new;
create_stack(&new);

C Stack pointing to Address?

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.

Stack TOP pointer is always null

I am creating a new stack using linked list. I dont know why the TOP pointer is always pointing to NULL. I think I am not setting the top pointer correctly, or it is not visible outside the function.
#include "stdio.h"
#include "stdlib.h"
typedef struct StackItem
{
int itemValue;
struct StackItem* NextItemPtr;
}StackItem;
typedef struct Stack
{
struct StackItem *TOP;
}Stack;
int IsStackEmpty(StackItem *TOP)
{
if(TOP==NULL)
return 1;
}
void pushItem(StackItem *headPtr,int n)
{
StackItem* Newnode;
Newnode=(StackItem*)malloc(sizeof(StackItem));
Newnode->itemValue=n;
printf("Checking Head TOP %d\n\n",IsStackEmpty(headPtr)); //Everytime it is giving 1
Newnode->NextItemPtr=IsStackEmpty(headPtr)?NULL:headPtr;
headPtr=Newnode;
}
int main()
{
Stack* stackptr;
stackptr=(Stack*)malloc(sizeof(Stack));
stackptr->TOP=NULL;
pushItem(stackptr->TOP,3);
pushItem(stackptr->TOP,6);
return 0;
}
This statement does nothing for the caller:
headPtr=Newnode;
You can:
Pass a double pointer and assign to *headPtr
Return Newnode instead of assigning to headPtr
This C FAQ explains this very subject.
headPtr = Newnode;
Since headPtr is an argument of the function, it's passed by value. Modifying it inside the function does not have any effect in the caller. You need to pass a pointer to it and modify it through the pointer:
void pushItem(StackItem **headPtr, int n)
*headPtr = NewNode;

Resources