You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 15:00:18