Ошибка сегментации (ядро сброшено), но не удается найти ошибку - PullRequest
0 голосов
/ 31 октября 2018
#include <stdlib.h>
#include <stdio.h>
#include "stack.h"

struct stack {
    // ... SOME CODE MISSING HERE ...
    int top;
    int stackArray[STACK_SIZE];
    int push;
    int pop;
};

struct stack *stack_init() {
    struct stack* s = (struct stack*) malloc(sizeof(struct stack));
    s->top = 0;

    if (s == NULL)
        return NULL;
    else
        return s;
}

void stack_cleanup(struct stack* s) {

    for(int i = 0; i < STACK_SIZE; i++)
        s->stackArray[i] = 0;

    free(s);
}

int stack_push(struct stack *s, int c) {

    if (s->top <= STACK_SIZE){
        s->stackArray[s->top] = c;
        s->top++;
        s->push++;
        return 0;
    }
    else
        return 1;


}

int stack_pop(struct stack *s) {

    if (!stack_empty(s)){
        return s->stackArray[s->top];
        s->top--;
        s->pop++;
    }
    else
        return -1;
}

int stack_peek(struct stack *s) {

    if (!stack_empty(s)){
        return s->stackArray[s->top];
    }
    else
        return -1;
}

int stack_empty(struct stack *s) {

    if (s->top == -1)
        return 1;
    else
        return 0;
}

int main(){
    struct stack *test;
    // stack_peek(test);
    // return 0;
    printf("%d\n", test->top);
}

Я пытаюсь реализовать действительно базовый стек, используя C для задания колледжа, и я пытаюсь проверить реализацию, но она выдает только ошибку Segmantation fault (Core Dumped). Я провел некоторое исследование в Интернете, но не смог найти то, что могло бы мне помочь. Я понимаю, что Segmentation Fault Core Dumped означает, что я получаю доступ к чему-то, чего я не могу / не должен получить, но я не знаю, как это относится к моему коду.

Спасибо.

1 Ответ

0 голосов
/ 31 октября 2018

Лучше всего запустить его с помощью gdb и получить дорожку стека с помощью команды bt cmd после ее segfaults. Я добавил некоторые комментарии к вашему исходному коду, которые могут или не могут исправить вашу проблему, но основной был явно сломан. «test» в main никогда не был назначен чему-либо, поэтому test-> top является попыткой разыменования любого адреса, назначенного «test», который может быть любым значением мусора, которое находится в «памяти стека программ» в данный момент. Обязательно инициализируйте свои переменные перед их использованием.

#include <stdlib.h>
#include <stdio.h>
#include "stack.h"

struct stack {
    // ... SOME CODE MISSING HERE ...
    int top;
    int stackArray[STACK_SIZE];
    int push;
    int pop;
};

struct stack *stack_init() {
    struct stack* s = (struct stack*) malloc(sizeof(struct stack));
    s->top = 0; // HERE IS A POTENTIAL NULL POINTER DEREFENCE, MOVE THIS AFTER THE NULL CHECK

    if (s == NULL)
        return NULL;
    else
        //HERE IS WHERE THE ABOVE LINE SHOULD BE LOCATED. s->top = 0;
        //WHAT ABOUT THE REST OF THE MEMORY IN THIS STRUCTURE, SHOULD IT BE 0?
        return s;
}

void stack_cleanup(struct stack* s) {

    for(int i = 0; i < STACK_SIZE; i++)
        s->stackArray[i] = 0;

    free(s);
}

int stack_push(struct stack *s, int c) {

    if (s->top <= STACK_SIZE){ //CAN s->top EVER BE NEGATIVE?
        s->stackArray[s->top] = c; //BECAUSE THIS WOULD BE A BAD INDEX IF IT WERE NEGATIVE HERE
        s->top++;
        s->push++;
        return 0;
    }
    else
        return 1;


}

int stack_pop(struct stack *s) {

    if (!stack_empty(s)){
        return s->stackArray[s->top];
        s->top--;//THIS LOOKS LIKE IT WILL NEVER GET EXECUTED
        s->pop++;//SAME WITH THIS LINE, MOVE THEM ABOVE THE RETURN STATEMENT IF YOU WANT THEM TO BE EXECUTED.
    }
    else
        return -1;
}

int stack_peek(struct stack *s) {

    if (!stack_empty(s)){
        return s->stackArray[s->top];
    }
    else
        return -1;
}

int stack_empty(struct stack *s) {

    if (s->top == -1)
        return 1;
    else
        return 0;
}

int main(){
    struct stack *test; //EITHER MALLOC MEMORY FOR THIS GUY OR PUT IT ON THE STACK (stack vs heap memory)
    //SAMPLE STACK USAGE, DOESNT USE YOUR INIT FUNCTION
    struct stack test;
    memset(test, 0, sizeof test);

    //IF YOU DONT WANT TO MALLOC YOU CAN POINT IT TO THE STACK VERSION ABOVE
    struct stack *test2 = &test; //NOW YOU DONT NEED MALLOC, BUT YOU STILL DIDNT USE YOUR SPECIAL INIT.
    // stack_peek(test);
    // return 0;
    printf("%d\n", test->top);
}

Во всех моих комментариях к обзору кода стек ссылок относится к памяти стека в программе c, а не к структуре, которую вы здесь определяете (которая также является стеком, так что это немного запутанно). https://www.geeksforgeeks.org/memory-layout-of-c-program/

...