将项目添加到堆栈会使其崩溃
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;
}
我正在尝试自己(为了更好地理解)用 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;
}