修复分段错误
Fix segmentation fault
我正在尝试使用两个堆栈制作一个中缀程序的后缀。基本思路是这样的 -
ptr1 --> ptr2 --> ptr3 --> ptr4 --> NULL
| ---------- | ------ | ---------- |
(4*5) ----5 -------- 6 -------- 10
每个操作数都是一个单独的栈,ptr栈是每个操作数第一个元素的内存地址。但是我遇到了分段错误。我认为这是由于
(*ptr) = (*ptr)->next1; pop 函数中的语句。有人可以 explain/fix 做一个 pop 函数 returns 顶部操作数堆栈的地址并同时弹出 ptr 堆栈吗?完整代码-
struct bracket {
char c;
struct bracket* next;
};
struct outer {
struct bracket *down;
struct outer *next1;
};
struct outer* push_ptr (struct bracket *ptr,struct outer * out){
struct outer *temp = NULL;
temp = (struct outer*)malloc(sizeof(struct outer));
temp->down = ptr;
temp->next1 = out;
return temp;
}
struct bracket* push_ch(char ch,struct bracket *head){
struct bracket *temp = NULL;
temp = (struct bracket*)malloc(sizeof(struct bracket));
temp->c = ch;
temp->next = head;
return temp;
}
struct bracket* pop(struct outer **ptr){
struct bracket *top = (struct bracket*)malloc(sizeof(struct bracket));
top = (*ptr)->down;
(*ptr) = (*ptr)->next1;
return top;
}
int main(){
char c[] = "25,9,6,/,-,3,/";
struct outer * address = NULL;
struct bracket * num;
for (int i=0;i<strlen(c);i=i+1){
if(c[i]==',') continue;
else if (c[i]=='*' || c[i]=='-' || c[i]=='+' || c[i]=='/'){
struct bracket *top1 = pop(&address);
struct bracket *top2 = pop(&address);
}
else {
num = NULL;
while(c[i]!=','){
num = push_ch(c[i],num);
i = i+1;
}
address = push_ptr(num,address);
}
}
return 0;
}
你的问题肯定出在函数pop()...
struct bracket* pop(struct outer **ptr){
struct bracket *top = (struct bracket*)malloc(sizeof(struct bracket));
top = (*ptr)->down;
(*ptr) = (*ptr)->next1;
return top;
}
你每次都从外部 ptr 弹出,最终,在某个时候,它将保持为空。让我们了解当它为空时会发生什么。所以你传递了一个指向 NULL 的引用 struct outer **ptr。因此它将无法在这一行检索 (*ptr)->down ...
top = (*ptr)->down;
并且您将遇到分段错误。
你应该在你的 pop 函数中处理 NULL 情况(一般来说,NULL 保护每个函数是很好的)。 pop 函数的另一种实现可能是这样...
struct bracket* pop(struct outer **ptr){
struct bracket *top = (struct bracket*)malloc(sizeof(struct bracket));
if (*ptr)
{
top = (*ptr)->down;
(*ptr) = (*ptr)->next1;
}
else
top = NULL;
return top;
}
这将修复分段错误。如果外部结构不包含任何元素,它将 return NULL。
我正在尝试使用两个堆栈制作一个中缀程序的后缀。基本思路是这样的 -
ptr1 --> ptr2 --> ptr3 --> ptr4 --> NULL
| ---------- | ------ | ---------- |
(4*5) ----5 -------- 6 -------- 10
每个操作数都是一个单独的栈,ptr栈是每个操作数第一个元素的内存地址。但是我遇到了分段错误。我认为这是由于 (*ptr) = (*ptr)->next1; pop 函数中的语句。有人可以 explain/fix 做一个 pop 函数 returns 顶部操作数堆栈的地址并同时弹出 ptr 堆栈吗?完整代码-
struct bracket {
char c;
struct bracket* next;
};
struct outer {
struct bracket *down;
struct outer *next1;
};
struct outer* push_ptr (struct bracket *ptr,struct outer * out){
struct outer *temp = NULL;
temp = (struct outer*)malloc(sizeof(struct outer));
temp->down = ptr;
temp->next1 = out;
return temp;
}
struct bracket* push_ch(char ch,struct bracket *head){
struct bracket *temp = NULL;
temp = (struct bracket*)malloc(sizeof(struct bracket));
temp->c = ch;
temp->next = head;
return temp;
}
struct bracket* pop(struct outer **ptr){
struct bracket *top = (struct bracket*)malloc(sizeof(struct bracket));
top = (*ptr)->down;
(*ptr) = (*ptr)->next1;
return top;
}
int main(){
char c[] = "25,9,6,/,-,3,/";
struct outer * address = NULL;
struct bracket * num;
for (int i=0;i<strlen(c);i=i+1){
if(c[i]==',') continue;
else if (c[i]=='*' || c[i]=='-' || c[i]=='+' || c[i]=='/'){
struct bracket *top1 = pop(&address);
struct bracket *top2 = pop(&address);
}
else {
num = NULL;
while(c[i]!=','){
num = push_ch(c[i],num);
i = i+1;
}
address = push_ptr(num,address);
}
}
return 0;
}
你的问题肯定出在函数pop()...
struct bracket* pop(struct outer **ptr){
struct bracket *top = (struct bracket*)malloc(sizeof(struct bracket));
top = (*ptr)->down;
(*ptr) = (*ptr)->next1;
return top;
}
你每次都从外部 ptr 弹出,最终,在某个时候,它将保持为空。让我们了解当它为空时会发生什么。所以你传递了一个指向 NULL 的引用 struct outer **ptr。因此它将无法在这一行检索 (*ptr)->down ...
top = (*ptr)->down;
并且您将遇到分段错误。 你应该在你的 pop 函数中处理 NULL 情况(一般来说,NULL 保护每个函数是很好的)。 pop 函数的另一种实现可能是这样...
struct bracket* pop(struct outer **ptr){
struct bracket *top = (struct bracket*)malloc(sizeof(struct bracket));
if (*ptr)
{
top = (*ptr)->down;
(*ptr) = (*ptr)->next1;
}
else
top = NULL;
return top;
}
这将修复分段错误。如果外部结构不包含任何元素,它将 return NULL。