Стек в C с ошибкой «Процесс возвратил -1073741819 (0xC0000005)» - PullRequest
0 голосов
/ 19 апреля 2020
#include <stdio.h>
#include <stdlib.h>
#define N 5

typedef struct stack{
    int top;
    int info[N];
} stack;

void initStack(stack *s);
void push(stack *s, int val);
void pop(stack *s);
int isFull(stack s);
int isEmpty(stack s);
void printStack(stack *s);

int main(){
    stack *s;
    initStack(&s);
    push(&s, 19);
    push(&s, 2);
    push(&s, 19);
    push(&s, 2);
    push(&s, 19);
    printStack(&s);

    return 0;
}

void initStack(stack *s){
    s->top = -1;
}

void push(stack *s, int val){
    if(isFull(*s) == 0){
        s->top++;
        s->info[s->top] = val;
    } else printf("Stack full!\n");
}

void pop(stack *s){
    if(isEmpty(*s) == 0) s->top--;
    else printf("Stack empty!\n");
}

int isFull(stack s){
    if(s.top == N-1) return 1;
    else return 0;
}

int isEmpty(stack s){
    if(s.top == -1) return 1;
    else return 0;
}

void printStack(stack *s){
    for(int i = 0; i < s->top + 1 && i < N; i++)
        printf("%d ", s->info[i]);
    printf("\n");
}

У меня проблемы с этим кодом ... я думаю, что пишу из стека (индекс связан), даже если теоретически у меня должны быть свободные позиции. Я получил ошибку:

Процесс вернул -1073741819 (0xC0000005)

Ответы [ 2 ]

1 голос
/ 19 апреля 2020

Вы передаете адрес указателя стека s в функции стека, такие как initStack (т. Е. Тип, переданный в initStack, pu sh, et c. Is stack **). Изменение объявления s внутри main() (и только main(), а не других функций) на stack s решит вашу проблему.

Если вы можете найти настройки предупреждений вашего компилятора, включите их , Они сообщат вам, когда произойдет что-то вроде этого несоответствия типов.

1 голос
/ 19 апреля 2020

вы определяете

void initStack(stack *s){

но вы звоните

stack *s;
initStack(&s);

вы определяете

void push(stack *s, int val){

но вы звоните

stack *s;
...
push(&s, 19);
push(&s, 2);
push(&s, 19);
push(&s, 2);
push(&s, 19);

вы определяете

void printStack(stack *s){

но вы звоните

 stack *s;
 ....
 printStack(&s);

Все ваши звонки недействительны

Замените

stack *s;

на

 stack s;

после этого, компиляция и выполнение:

pi@raspberrypi:/tmp $ gcc -Wall c.c
pi@raspberrypi:/tmp $ ./a.out
19 2 19 2 19 
pi@raspberrypi:/tmp $ 

При компиляции вашей версии вашим компилятором не было сообщений?


Вы не используете указатель для isFull и isEmpty (stack s) , вы получите ожидаемый результат (если вы действительно дадите stack в качестве аргумента, а не указатель на stack или что-то еще), но Делая, что стек копируется для заполнения параметра, это дороже, чем просто получить указатель, поэтому я рекомендую вам также получить указатель на стек , а не стек и вы также можете упростить Определение:

int isFull(stack * s);
int isEmpty(stack * s);

...

int isFull(stack * s) {
    return (s->top == N-1);
}

int isEmpty(stack * s) {
    return (s.top == -1);
}

Чтобы вернуться к исходной проблеме, имея:

stack s;
stack * p;
stack ** pp;
  • s - это стек, это означает блок памяти, способный запомнить N + 1 int
  • p - указатель на стек, то есть p может запомнить адрес стека, но этот указатель полезен только в том случае, если он указывает на существующий стек
  • pp - это указатель на указатель на стек (двойной указатель), что означает pp может запомнить адрес указателя на стек, но опять же pp полезен только в том случае, если он указывает на существующий указатель на стек.

добавление инициализации:

stack s;
stack * p = &s;
stack ** pp = &p;

s.top = -1;

у нас есть:

  • s.top == -1
  • , потому что p укажите с у нас есть * p == s и p-> top == -1 (обратите внимание, что p-> top и (* p) .top - это два способа написания одной и той же вещи, "->" - это сокращение сделать код более читабельным)
  • , потому что pp указывают на p , мы имеем * pp == p , а затем * * pp == s и (* pp) -> top == -1

В вашем коде вызов типа initStack (& ​​s); дает адрес s , где s определяет неинициализированный указатель на стек , но для initStack его аргумент является указателем на действительный стек , а не указатель на неинициализированный указатель на стек => s-> top = -1; не может работать.

Допустимый код, где s является указателем на стек и дает & s в качестве аргумента initStack должно быть примерно так:

void initStack(stack ** s){
 (*s)->top = -1;
}

...

stack st;
stack * s = &st;

initStack(&s);

но, конечно, это слишком сложно ни для чего, сравните с кодом, который я уже дал

...