Lex程序触发stack smashing检测错误,请求代码排查
Lex程序栈溢出错误排查
问题描述
我编写了如下Lex程序,但运行时出现错误:
*** stack smashing detected ***: terminated Aborted (core dumped)
已多次检查代码却未找到问题,恳请帮忙排查错误。
原始代码
%{ #include <stdio.h> #include <string.h> int WordLength=0; char LongestWord[200]; int arrayIndex=0; double num[2000]={0}; int numofvowel=0; char VowelArray[100][100]; int IngNum=0; int numLine=0; %} %% [aeiouAEIOU][a-zA-Z]+ {strcpy(VowelArray[numofvowel], yytext);numofvowel+=1;} [.+ing]+ {IngNum+=1;} [0-9]+ {if(atof(yytext) > 500) {num[arrayIndex]=atof(yytext);arrayIndex+=1;} } [a-zA-Z]+ {if (yyleng > WordLength) { WordLength=yyleng; strcpy(LongestWord,yytext); } } [/n] {numLine++;} . ; %% int yywrap(){ return 1;} int main(int argc[] , char **argv[]){ char file[] = ""; printf("Enter the file name : "); scanf("%s", file); extern FILE *yyin ; yyin=fopen(file, "r"); yylex(); printf("The longest word is %s ",LongestWord); printf("/n"); printf("The numbers that are greater than 500 are: "); for(int i=0 ; i<arrayIndex ; i++){ printf("%f, ",num[i]);} printf("There are %d words that start with vowel letter. They are:",numofvowel); for (int k = 0; k < numofvowel; k++){ printf("%s, ", VowelArray[k]);} printf("The number of words that are ended by ”ing”: %d ",IngNum); printf("The number of lines %d ",numLine); return 0; }
错误信息
*** stack smashing detected ***: terminated Aborted (core dumped)
错误原因及修复方案
1. 文件名缓冲区长度不足导致栈溢出
main函数中char file[] = "";仅分配了1字节内存(仅存终止符\0),但scanf("%s", file)会读取任意长度的文件名,直接写入会破坏栈内存,触发栈溢出检测。
修复:给file分配足够长度的缓冲区:
char file[256] = "";
2. 换行符匹配规则错误
规则[/n]会匹配字符/或n,无法识别真正的换行符,导致行数统计失效,还会让换行符被最后一条.规则忽略。
修复:将规则改为匹配标准换行符:
\n {numLine++;}
3. "ing"结尾单词的匹配规则错误
[.+ing]+是字符集匹配,会匹配任意包含.、+、i、n、g的字符序列,而非以ing结尾的单词。且当前规则顺序靠后,会被[a-zA-Z]+优先匹配。
修复:调整规则顺序(Lex优先匹配先定义的规则),修改为:
[a-zA-Z]+ing {IngNum+=1;}
4. 数组越界风险
strcpy未做长度检查,若输入单词超过LongestWord或VowelArray的长度,会直接溢出栈内存。
修复:使用strncpy并手动添加终止符,同时增加边界检查:
- 对于
LongestWord:
if (yyleng > WordLength && yyleng < sizeof(LongestWord)) { WordLength = yyleng; strncpy(LongestWord, yytext, sizeof(LongestWord)-1); LongestWord[sizeof(LongestWord)-1] = '\0'; }
- 对于
VowelArray:
if (numofvowel < 100 && yyleng < 100) { strncpy(VowelArray[numofvowel], yytext, 99); VowelArray[numofvowel][99] = '\0'; numofvowel += 1; }
5. main函数参数不符合标准
int main(int argc[] , char **argv[])不符合C标准,可能导致栈帧异常。
修复:改为标准声明:
int main(int argc, char **argv) { // ... }
6. 输出换行符错误
printf("/n");会输出字符/n而非换行,需改为printf("\n");。
修复后的完整代码
%{ #include <stdio.h> #include <string.h> #include <stdlib.h> int WordLength = 0; char LongestWord[200]; int arrayIndex = 0; double num[2000] = {0}; int numofvowel = 0; char VowelArray[100][100]; int IngNum = 0; int numLine = 0; %} %% [a-zA-Z]+ing {IngNum += 1;} [aeiouAEIOU][a-zA-Z]+ { if (numofvowel < 100 && yyleng < 100) { strncpy(VowelArray[numofvowel], yytext, 99); VowelArray[numofvowel][99] = '\0'; numofvowel += 1; } } [0-9]+ { double val = atof(yytext); if (val > 500 && arrayIndex < 2000) { num[arrayIndex] = val; arrayIndex += 1; } } [a-zA-Z]+ { if (yyleng > WordLength && yyleng < sizeof(LongestWord)) { WordLength = yyleng; strncpy(LongestWord, yytext, sizeof(LongestWord)-1); LongestWord[sizeof(LongestWord)-1] = '\0'; } } \n {numLine++;} . ; %% int yywrap() { return 1; } int main(int argc, char **argv) { char file[256] = ""; printf("Enter the file name : "); scanf("%s", file); extern FILE *yyin ; yyin = fopen(file, "r"); if (!yyin) { perror("Failed to open file"); return 1; } yylex(); printf("The longest word is %s\n", LongestWord); printf("The numbers that are greater than 500 are: "); for(int i=0 ; i<arrayIndex ; i++){ printf("%f, ", num[i]); } printf("\n"); printf("There are %d words that start with vowel letter. They are: ", numofvowel); for (int k = 0; k < numofvowel; k++){ printf("%s, ", VowelArray[k]); } printf("\n"); printf("The number of words that end with \"ing\": %d\n", IngNum); printf("The number of lines: %d\n", numLine); fclose(yyin); return 0; }
内容的提问来源于stack exchange,提问作者nada 1422
相关产品推荐
相关产品推荐

