C语言括号平衡检测程序触发栈溢出问题的修复求助
问题根因
- 缺少必要头文件与结构体定义:代码未引入
<stdio.h>、<stdlib.h>等依赖头文件,也没有定义struct sNode结构体,本身无法直接编译。 - 栈弹出逻辑错误:输出待补全括号的循环中,单次循环连续调用3次
pop(),每次循环最多弹出3个栈元素,远超出预期的1个。栈内剩余元素不足时会触发空栈弹出逻辑,你误将空栈弹出的错误提示写为"Stack overflow"(实际为栈下溢),和实际问题完全不符。 - 输入字符串未正确终止:
main函数申请exp内存时仅分配了strlen(argv[1])的长度,没有预留字符串结束符\0的空间,复制后也未手动补结束符,导致括号遍历逻辑越界访问内存,触发未知错误。 - 平衡状态返回值不符合预期:
areBracketsBalanced函数注释标注平衡时返回1,实际平衡分支返回的是0,逻辑不统一。
修复方案
1 补充所需头文件与struct sNode结构体定义。
2 修改待补全括号输出逻辑:每次循环仅调用1次pop(),将弹出值存入临时变量后再做匹配判断,避免多余弹栈操作。
3 修正输入字符串内存分配逻辑:申请内存时长度+1,复制完成后补充\0结束符,保证字符串正确终止。
4 修正空栈弹出的错误提示为"Stack underflow",同时修改平衡场景返回值为1,匹配注释逻辑。
修复后完整代码
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> struct sNode { char data; struct sNode* next; }; void push(struct sNode** top_ref, int new_data){ struct sNode* new_node = (struct sNode*)malloc(sizeof(struct sNode)); if (new_node == NULL) { printf("Stack overflow \n"); getchar(); exit(0); } new_node->data = new_data; new_node->next = (*top_ref); (*top_ref) = new_node; } int pop(struct sNode** top_ref){ char res; struct sNode* top; if (*top_ref == NULL) { printf("Stack underflow \n"); getchar(); exit(0); }else { top = *top_ref; res = top->data; *top_ref = top->next; free(top); return res; } } // Returns 1 if character1 and character2 are matching left and right Brackets bool isMatchingPair(char character1, char character2) { if (character1 == '(' && character2 == ')') return 1; else if (character1 == '{' && character2 == '}') return 1; else if (character1 == '[' && character2 == ']') return 1; else return 0; } // Return 1 if expression is balanced int areBracketsBalanced(char exp[]){ int i = 0; struct sNode* stack = NULL; while (exp[i]){ if (exp[i] == '{' || exp[i] == '(' || exp[i] == '[') push(&stack, exp[i]); if (exp[i] == '}' || exp[i] == ')' || exp[i] == ']') { if (stack == NULL){ printf("%d:%c\n",i,exp[i]); return 0; }else if (!isMatchingPair(pop(&stack), exp[i])){ printf("%d:%c\n",i,exp[i]); return 0; } } i++; } if (stack != NULL){ printf("open: "); while(stack!=NULL){ // 单次循环只弹一次栈,存入临时变量判断 char left = pop(&stack); if(left == '('){ printf("%c",')'); }else if(left == '['){ printf("%c",']'); }else if(left == '{'){ printf("%c",'}'); } } printf("\n"); return 0; } // 平衡时返回1,无输出 return 1; } int main(int argc, char* argv[]) { if (argc < 2) { return 0; } // 分配长度+1,预留结束符位置 char *exp = (char *)malloc((strlen(argv[1]) + 1) * sizeof(char)); for(int i = 0; i < strlen(argv[1]); i++){ exp[i] = argv[1][i]; } // 补充字符串结束符 exp[strlen(argv[1])] = '\0'; areBracketsBalanced(exp); free(exp); return 0; }
内容的提问来源于stack exchange,提问作者user15409086
相关产品推荐
相关产品推荐

