first time posting here, any help would be appreciated. I'm trying to change the value "size" inside my stack called "try", by putting it through my function called Stack_Init. If I print out the value of "stack->size" inside the function, it gives me the correct value for size (being 4). If I were to print
try->size after executing my function (at the end of the code), it would give me a value of 0.
struct intnode {
int data;
struct intnode *next;
}; typedef struct intnode node;
struct stack {
node *top;
int size;
}; typedef struct stack Stack;
void Stack_Init(Stack *S, int size){
Stack *stack = malloc(size*sizeof(node));
stack->top = NULL;
stack->size = size;//for some reason, this doesn't change try->size
}
int main(){
Stack *try;
int size = 4;
Stack_Init(try,size);
printf("%d %d ", try->size, try->top);
Thanks for reading!
You are trying to change a pointer that you pass to the function, so you need an extra level of indirection, i.e. a pointer to pointer. In addition, you need to assign to dereferenced parameter instead of a local variable:
void Stack_Init(Stack **S, int size){
// ^
// |
// Extra asterisk here
*S = malloc(size*sizeof(node));
// ^
// |
// Dereference the pointer passed into the function
(*S)->top = NULL;
(*S)->size = size;
}
The call to the function needs to look like this:
Stack_Init(&try,size);
// ^
// |
// Pass a pointer to a pointer
Your Stack_Init function has a couple problems with it. You are modifying a local variable instead of the argument passed to the function, and you're assigning the memory incorrectly. Try this instead.
void Stack_Init(Stack **S,int size) {
Stack *stack = (Stack*)malloc(sizeof(Stack));
stack->top = NULL;
stack->size = size;
*S = stack;
}
Related
stack.h
#define MAX_STACK 10
typedef int STACK_ITEM;
typedef struct Stack *STACK ;
stack.c
#include"stack.h"
struct Stack{
STACK_ITEM contents[MAX_STACK];
int tos;
};
_Bool create_stack(STACK s){
s = malloc(sizeof(struct Stack));
if(s == NULL )
return 0;
s->tos = 0;
return 1;
}
When calling the create_stack function, it doesn't affect s (pointer to structure) at all. So, my question is: why is s not changing, even though it is a pointer, not a value, passed?
Remember, all parameters are passed by value in C.
When you pass a pointer as a function parameter, you can access the object (or array of objects) pointed to by that pointer.
Your create_stack() is passed a pointer to a struct Stack, that is the s parameter. It then ignores the original value of s and reassigns it. That is allowed, but note that it does not change the original pointer in the caller of create_stack() because function parameters are passed by value.
There are two ways to do what you want.
The first way is to pass a pointer to a pointer:
_Bool create_stack(STACK *s){
*s = malloc(sizeof(struct Stack));
if(*s == NULL )
return 0;
(*s)->tos = 0;
return 1;
}
Call it e.g.:
STACK mystack;
_Bool ret;
ret = create_stack(&mystack);
if (!ret) {
/* error */
}
The second way is to not pass anything and return a pointer to the allocated stack:
STACK create_stack(void){
STACK s = malloc(sizeof(struct Stack));
if(s != NULL ) {
s->tos = 0;
}
return s;
}
Call it e.g.:
STACK s;
s = create_stack();
if (s == NULL) {
/* error */
}
Finally, as a point of programming style, do not typedef pointers in the way you have done. It is clearer if the pointer is explicit, for example, use typedef struct Stack STACK; instead of typedef struct Stack *STACK; and adjust the usage accordingly, for example, replacing STACK s with STACK *s and replacing STACK *s with STACK **s.
Function parameters are its local variables. That is the parameters hold copies of the passed arguments. To change an original argument in a function you have to pass it by reference through pointer.
So change the function like
_Bool create_stack(STACK *s){
*s = malloc(sizeof(struct Stack));
if(*s == NULL )
return 0;
( *s )->tos = 0;
return 1;
}
In order for a C function to modify an argument, the argument must be given as a pointer to the value to be changed. Thus, for a simple integer argument:
void Inc(int *value) {
++(*value);
}
will do the trick, but:
void Inc(int value) {
++value;
}
will do absolutely nothing to any argument given in a call to Inc, as the function just gets a copy of the 'value' given.
The same goes for a pointer! Your function just changes a copy of the pointer it is passed. So, you should change your function to take a pointer to the pointer:
_Bool create_stack(STACK *s){ // Pointer to a pointer to Stack
*s = malloc(sizeof(struct Stack)); // Change the value of the STACK object pointed to
if (*s == NULL )
return 0;
(*s)->tos = 0; // And, again, we need to (singly) dereference to 'double' pointer
return 1;
}
Then, in your calling code, where you originally have something like:
_Bool answer = create_stack(myStackPointer);
you would need to add the address of your pointer:
_Bool answer = create_stack(&myStackPointer);
Feel free to ask for further clarification and/or explanation.
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.
first time posting here, any help would be appreciated. I'm trying to change the value "size" inside my stack called "try", by putting it through my function called Stack_Init. If I print out the value of "stack->size" inside the function, it gives me the correct value for size (being 4). If I were to print
try->size after executing my function (at the end of the code), it would give me a value of 0.
struct intnode {
int data;
struct intnode *next;
}; typedef struct intnode node;
struct stack {
node *top;
int size;
}; typedef struct stack Stack;
void Stack_Init(Stack *S, int size){
Stack *stack = malloc(size*sizeof(node));
stack->top = NULL;
stack->size = size;//for some reason, this doesn't change try->size
}
int main(){
Stack *try;
int size = 4;
Stack_Init(try,size);
printf("%d %d ", try->size, try->top);
Thanks for reading!
You are trying to change a pointer that you pass to the function, so you need an extra level of indirection, i.e. a pointer to pointer. In addition, you need to assign to dereferenced parameter instead of a local variable:
void Stack_Init(Stack **S, int size){
// ^
// |
// Extra asterisk here
*S = malloc(size*sizeof(node));
// ^
// |
// Dereference the pointer passed into the function
(*S)->top = NULL;
(*S)->size = size;
}
The call to the function needs to look like this:
Stack_Init(&try,size);
// ^
// |
// Pass a pointer to a pointer
Your Stack_Init function has a couple problems with it. You are modifying a local variable instead of the argument passed to the function, and you're assigning the memory incorrectly. Try this instead.
void Stack_Init(Stack **S,int size) {
Stack *stack = (Stack*)malloc(sizeof(Stack));
stack->top = NULL;
stack->size = size;
*S = stack;
}
I am currently working on stacks right now. I am supposed to use the following structures and function prototypes:
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);
Here is my actual code for create_stack() and push():
stack* create_stack()
{
stack *stack;
stack = malloc(sizeof(stack));
stack->size = 0;
stack->stack = NULL;
return stack;
}
void push(stack* s, char val)
{
stack *newStack;
newStack = create_stack();
newStack->stack->data = val;
newStack->stack = s->stack;
s = newStack;
}
I am getting a segmentation fault when I try to store char val into newStack->stack->data. How does this not work? What do I need to do to make this stack on top???
The push function is wrong.
void push(stack* s, char val)
{
stack *newStack;
newStack = create_stack(); /* new stack created, why not work on the existing one ? */
newStack->stack->data = val; /* you're writing to a NULL pointer */
newStack->stack = s->stack;
s = newStack; /* this will not be visible from outside the function */
}
First of all, you are trying to recreate a new stack for each call of this function, which is certainly not what is intended.
If you try to modify the value of s, it will not be visible from outside the function, and you will still have your original stack.
Then, you are accessing the stack->data member even though stack has no space allocated to it yet (because you set it to NULL). You actually set it right after, which is why it crashes, most probably.
You probably want to do something like this:
void push(stack* s, char val)
{
node * n;
/* go to the end of the "stack" */
n = s->stack;
while (n != NULL) {
n = n->next;
}
/* allocate memory for a new node */
n = malloc(sizeof(node));
/* initialize node */
n->data = val;
n->next = NULL;
/* increment stack size */
s->size++;
}
And as mentionned before, this is merely a singly-linked list which is not the best fit for a stack, because as it exists now, you have to follow the node pointers to reach the last element, which makes push and pop operations O(N).
A faster implementation would look like this:
void push(stack* s, char val)
{
node * first_node, * new_node;
first_node = s->stack;
/* allocate memory for a new node */
new_node = malloc(sizeof(node));
/* initialize node */
new_node->data = val;
new_node->next = first_node;
/* increment stack size */
s->stack = new_node;
s->size++;
}
The top of the stack is always the first node, and the performance is O(1).
Follow your code....
stack *newStack = create_stack(); // in push()
newStack = malloc(sizeof(stack)); // in create_stack()
newStack->stack = NULL; // in create_stack()
newStack->stack->data = val; // in push()... this is where you crash.
Because newStack->stack is a NULL pointer. Your create_stack() function sets it to NULL, and you then dereference it. You have to allocate a struct node somewhere.
This code also has some readability issues which might be contributing to the problem. You are naming variables the same names as their types, which is very confusing. Consider using some other naming pattern like stack_t for types and stack for variable names.
I'm trying to implement a Queue in C (using a Linked List) to store pointers to data. The en-queuing seems to be working fine, but some trouble with pointers upon de-queuing.
In my main():
void* data = malloc(sizeof(int));
dequeue(&Q, data);
printf("(%d) %d\n", k, *(int*)data);
dequeue():
int dequeue(struct queue *q, void *value)
{
struct queue_node *tmp;
if (!q->first) {
value = 0;
return 1;
}
value = q->first->data;
tmp = q->first;
if (q->first == q->last)
q->first = q->last = NULL;
else
q->first = q->first->next;
free(tmp);
return 0;
}
Based on my debugging, it seems that the value of the *data pointer in the main() for loop doesn't retain the value that it's set to in dequeue(). What am I missing?
Edit:
struct queue_node
{
struct queue_node *next;
void* data;
};
struct queue
{
struct queue_node *first;
struct queue_node *last;
};
The queue_node's data holds a pointer to some value (here it is an int, but it may not be true always, otherwise you'd use an int instead...)
Since this value was allocated with malloc (and is not a local variable) you need to also free it at some point.
So, change the function's signature to accept a void**, don't allocate space for an int in main() but call dequeue with &data as a parameter, where void * data = 0. Don't forget to free data when done.
In dequeue, set *value = q->first->data.
You're setting the value of the "value" variable, which is a pointer local to the function.
If you want to set the value to which it points, use:
*value = 0;
and:
*value = q->first->data;
Edit (after question edit): Since queue_node.data is itself a pointer, it makes more sense to pass a void**, as #Andrei notes above.
Assuming data is a (void *) and you want the (int) value pointed to by data, you'll have to replace
value = q->first->data;
with
*(int *)value = *(int *)q->first->data;
in the function deque();