Home > Mobile >  Getting a segmentation fault error for stack in C
Getting a segmentation fault error for stack in C

Time:10-14

I have a stack struct that has the a dynamic double pointer array of char that performs the simple stack operations. I initialize the memory with calloc to have definite values in the array. It reallocs space after the size of the array reaches 10 elements.

The stack struct for my code:

typedef struct Stack{
    unsigned int size; //The current number of elements in the stack
    char **stk; //The actual stack represented by an array of strings
    unsigned int arrsize; //To track the size of the array; gets incremented by 10 after limit
}stack;

Code for my stack file:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "stack.h"

#define MULTIPLIER 10
#define MAX_STR 1024

stack *createstack(void){
    stack *s = malloc(sizeof(stack));
    if(s == NULL){
        perror("Failed to malloc!\n");
        return NULL;
    }

    s->size = 0;
    s->arrsize = MULTIPLIER;

    s->stk = calloc(MULTIPLIER, sizeof(char*));
    for (int i = 0; i < MULTIPLIER; i  ){
        s->stk[i] = calloc(MAX_STR, sizeof(char));
    }

    return s;
}


int isfull(const stack *s){
    if(s->size % MULTIPLIER == 0){
        return 0;
    }

    else{
        return 1;
    }
}

int isempty(const stack *s){
    if(s->size == 0){
        return 0;
    }
    else{
        return 1;
    }
}

void push(stack *s, char *item){
    if(isfull(s) == 0){
        char **temp = realloc(s->stk, (sizeof(char*)) * (MULTIPLIER   s->arrsize));
        s->arrsize  = MULTIPLIER;
        if(temp == NULL){
            perror("Realloc failed!");
        }
    }
    strcpy((s->stk)[s->size], item);
    s->size  = 1;
}

char *pop(stack *s){
    if(isempty(s) == 0){
        printf("Stack is empty!");
        return NULL;
    }

    else{
        char *tmp = (char*) malloc(strlen((s->stk)[s->size-1]));
        strcpy(tmp, (s->stk)[s->size-1]);
        s->size -= 1;
        return tmp;
    }
}

void destroy(stack *s){
    if(isempty(s) == 0){
        printf("Stack is already empty!");
    }
    else{
        for(size_t i=0; i < sizeof s; i  ){
            free((s->stk)[i]);
        }
        s->size = 0;
        free(s->stk);
        free(s);
    }
}

Now, when in the main function when I do something like

int main(){

    stack *stek = NULL;
    stek = createstack();

    push(stek, "first");
    push(stek, "second");
    push(stek, "third");

I get a "Segmentation fault (core dumped)" error for gcc. Upon checking gdb, I verified that it was being caused in the "strcpy" call in push(). Upon further speculation I got the idea that maybe the memory is not being assigned to the s->stk array even though I'm initializing it with calloc. Any help with figuring out how to fix this error would be appretiated.

Edit: Fixed some minor errors in the code after being pointed out in the comments.

CodePudding user response:

When push() reallocates (which it will needlessly do on the very first push), it does not update the stack structure with the pointer to the reallocated space. It is in no way safe to assume that the original pointer is still valid at that point, so the later attempt to dereference it is unsafe. This is probably the flaw responsible for the segfault.

Additionally, when push() expands the stack storage, it does not follow the model of createstack() by allocating space for the new elements to point to. That won't be the reason for the segfault you're seeing with the example main(), but it would be an issue if you pushed enough elements.

  • Related