Reputation: 9
I wanted to create a dynamic stack just for learning purposes, but I ran into a problem: I'd like to push()
function be able to handle if the dstack
isn't initialized, and it works when I go through the code in gdb
, but when I call the print_dstack()
after returning from push()
function, the pointer I give to it is NULL
(but I initialized *stack
and returned the pointer explicitly), so I'm getting stuck on SEGFAULT
at this point, because I am trying to read a pointer to NULL
. I wonder why does that even happen?
Here's my code:
dstack.h
:
#pragma once
#ifndef _DSTACK_H_
#define _DSTACK_H_
enum stack_inits {
DEFAULT_SIZE = 16,
DEFAULT_SPACE = 32
};
typedef struct {
int size;
int length;
int *stack;
} dstack_t;
static void *init(const int size);
static void resize(dstack_t *stack);
void *push(dstack_t *stack, int item);
void print_dstack(dstack_t const *stack);
void free_dstack(dstack_t *stack);
#endif
dstack.c
:
#include "dstack.h"
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
static void *init(const int size)
{
dstack_t *stack;
if( (stack = (dstack_t*)malloc(sizeof(dstack_t))) == NULL)
return NULL;
if( (stack->stack = (int*)malloc(size * sizeof(int))) == NULL) {
free(stack->stack);
free(stack);
return NULL;
}
stack->size = size;
stack->length = 0;
return stack;
}
static void resize(dstack_t *stack)
{
stack->size += DEFAULT_SPACE;
int *newStack = realloc(stack->stack, sizeof(int) * stack->size);
assert(newStack);
stack->stack = newStack;
}
void *push(dstack_t *stack, int item)
{
if(stack == NULL)
stack = init(DEFAULT_SIZE);
if(stack->stack == NULL)
if( (stack->stack = (int*)malloc(DEFAULT_SIZE * sizeof(int))) == NULL) {
free(stack->stack);
return NULL;
}
if(stack->length == stack->size)
resize(stack);
stack->stack[stack->length++] = item;
return &stack->stack[stack->length-1];
}
void print_dstack(dstack_t const *stack)
{
assert(stack);
for(int i = 0; i < stack->length; i++)
{
if(i % 2 == 0)
putchar('\0');
printf("stack[%d] = %d\t", i, stack->stack[i]);
}
}
void free_dstack(dstack_t *stack)
{
free(stack->stack);
free(stack);
}
stack_test.c
:
#include "dstack.h"
#include <stdio.h>
int main()
{
dstack_t *stack = NULL;
push(stack, 10);
print_dstack(stack);
free_dstack(stack);
return 0;
}
Upvotes: 0
Views: 48
Reputation: 385657
You modify push
's stack
, but not the caller's argument (main
's stack
), to which push
doesn't have access. If you want push
to modify the caller's pointer variable, you will need to pass a pointer to it as follows:
dstack_t * stack = NULL;
push( &stack, 10 );
You could also use something like the the following:
dstack_t * stack = NULL;
stack = push( stack, 10 );
Adjust push
accordingly.
Personally, I think it's appropriate for push
to require an initialized stack.
Upvotes: 0