将项目添加到堆栈会使其崩溃

Adding item to a stack make it crash

我正在尝试自己(为了更好地理解)用 C 语言实现 Stack 数据结构。

这是我目前得到的:

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

struct stack{
    //Data_Strucure: Stack of intgers
    int *stack;
    int size_of_stack;
    int elem_in_stack;
};

struct stack *creat_stack(unsigned int);
int push(struct stack *, int);
int pop(struct stack *);
int empty(struct stack *);
int peek(struct stack *);

int main(int argc, char *argv[]){
    int new_elem = 13;
    struct stack *new_stack = creat_stack(5);

    printf("%d %d\n", new_stack->size_of_stack, new_stack->elem_in_stack);

    //Crashes from here
    push(new_stack, new_elem);
    printf("%d\n", new_stack->stack[new_stack->size_of_stack]);

}

struct stack *creat_stack(unsigned int size){
    struct stack tmp;
    struct stack *ret_stack = &tmp;

    if((ret_stack->stack = malloc(sizeof(int) * size)) == NULL){
        fprintf(stderr, "Unable to allocate memory for the Stack.\n");
        exit(1);
    }
    ret_stack->size_of_stack = size;
    ret_stack->elem_in_stack = 0;

    return ret_stack;
}

int push(struct stack *stack, int nw_elem){
    int pos = stack->size_of_stack - stack->elem_in_stack;
    if(stack->size_of_stack == 0)
        return 1;
    stack->stack[pos] = nw_elem;
}

编译器returns我没报错。虽然我不明白为什么它在调用 push() 后崩溃。 请,如果可能的话,而不是解决方案代码,你能告诉我错误在哪里吗?这样我就可以理解它是如何影响整个程序的,并尝试自己解决它(这样下次就不会再发生了)。 感谢您提供任何有用的答案。

至少函数creat_stack不正确。

struct stack *creat_stack(unsigned int size){
    struct stack tmp;
    struct stack *ret_stack = &tmp;
    
    //...

    return ret_stack;
}

它return是一个指向本地对象的指针tmp,它在退出函数后将不存在。因此 returned 指针将无效并且取消引用此类指针会调用未定义的行为。

相反,您可以 return 函数中的对象本身。那就是函数声明可能看起来像

struct stack creat_stack(unsigned int size);

在主要部分你可以写

struct stack new_stack = creat_stack(5);

此外,函数 push 不会更改数据成员 elem_in_stack 并且它再次调用未定义的行为,因为当 elem_in_stack 等于 0 时,函数会尝试写入外部内存动态分配的数组。即在这种情况下 pos 等于 size_of_stack.

int push(struct stack *stack, int nw_elem){
    int pos = stack->size_of_stack - stack->elem_in_stack;
    if(stack->size_of_stack == 0)
        return 1;
    stack->stack[pos] = nw_elem;
}