代码在Windows(CodeBlocks)运行正常,Linux下触发stack smashing detected错误
问题:Linux下运行C代码提示"stack smashing detected",Windows正常
我的C语言代码在Windows的CodeBlocks中运行正常,但在Linux系统运行时,会提示“stack smashing detected”,除了棋盘外没有其他输出。代码如下:
#include <stdio.h> #include <stdlib.h> void inimatri(char mat[7][7]){ int l=0,c=0; while (l<8){ while (c<8){ mat[l][c]='.'; c=c+1; } c=0; l=l+1; } mat[3][3]='O'; mat[3][4]='X'; mat[4][3]='X'; mat[4][4]='O'; mat[2][5]='O'; mat[5][2]='O'; mat[3][2]='O'; mat[5][4]='O'; } void showmat (char mat[7][7]){ int l=0,c=0; printf(" 0 1 2 3 4 5 6 7"); while (l<8){ printf( "\n%d",l); while (c<8){ printf( " %c",mat[l][c]); c=c+1; } c=0; l=l+1; } } int hord(char mat[7][7], int l, int c, char pecaac){ int legal; if (c== 7){ return 0; } if (mat[l][c]!='.'){ return 0; } if (mat[l][c+1]==pecaac){ return 0; } while ((c+1)<8){ if (mat[l][c+1]=='.'){ return 0; } else if (mat[l][c+1]== pecaac){ return 1; } else{ legal= 0; } c=c+1; } return(legal); } int hore(char mat[7][7], int l, int c, char pecaac){ int legal=0; if (c== 0){ return 0; } if (mat[l][c]!='.'){ return 0; } if (mat[l][c-1]==pecaac){ return 0; } while (0<=(c-1)){ if (mat[l][c-1]=='.'){ return 0; } else if (mat[l][c-1]== pecaac){ return 1; } else { legal=0; } c=c-1; } return (legal); } int verb(char mat[7][7], int l, int c, char pecaac){ int legal; if (l== 7){ return 0; } if (mat[l][c]!='.'){ return 0; } if (mat[l+1][c]==pecaac){ return 0; } while ((l+1)<8){ if (mat[l+1][c]=='.'){ return 0; } else if (mat[l+1][c]== pecaac){ return 1; } else{ legal=0; } l=l+1; } return (legal); } int verc(char mat[7][7], int l, int c, char pecaac){ int legal; if (l== 0){ return 0; } if (mat[l][c]!='.'){ return 0; } if (mat[l-1][c]==pecaac){ return 0; } while (0<=(l-1)){ if (mat[l-1][c]=='.'){ return 0; } else if (mat[l-1][c]== pecaac){ return 1; } else{ legal = 0; } l=l-1; } return (legal); } int diads(char mat[7][7], int l, int c, char pecaac){ int legal; if (l== 0 || c== 7){ return 0; } if (mat[l][c]!='.'){ return 0; } if (mat[l-1][c+1]==pecaac){ return 0; } while (0<=(l-1) && c+1<8){ if (mat[l-1][c+1]=='.'){ return 0; } else if (mat[l-1][c+1]== pecaac){ return 1; } else{ legal = 0; } l=l-1; c=c+1; } return (legal); } int diadi(char mat[7][7], int l, int c, char pecaac){ int legal; if (l== 7 || c== 7){ return 0; } if (mat[l][c]!='.'){ return 0; } if (mat[l+1][c+1]==pecaac){ return 0; } while ((l+1)<8 && (c+1)<8){ if (mat[l+1][c+1]=='.'){ return 0; } else if (mat[l+1][c+1]== pecaac){ return 1; } else{ legal = 0; } l=l+1; c=c+1; } return (legal); } int diaes(char mat[7][7], int l, int c, char pecaac){ int legal; if (l== 0 || c== 0){ return 0; } if (mat[l][c]!='.'){ return 0; } if (mat[l-1][c-1]==pecaac){ return 0; } while (0<=(l-1) && 0<=(c-1)){ if (mat[l-1][c-1]=='.'){ return 0; } else if (mat[l-1][c-1]== pecaac){ return 1; } else{ legal = 0; } l=l-1; c=c-1; } return (legal); } int diaei(char mat[7][7], int l, int c, char pecaac){ int legal; if (l== 7 || c== 0){ return 0; } if (mat[l][c]!='.'){ return 0; } if (mat[l+1][c-1]==pecaac){ return 0; } while ((l+1)<8 && 0<=(c-1)){ if (mat[l+1][c-1]=='.'){ return 0; } else if (mat[l+1][c-1]== pecaac){ return 1; } else{ legal = 0; } l=l+1; c=c-1; } return (legal); } int clegal(char mat[7][7], int l, int c, char pecaac){ int ld,le,lc,lb; int ldi, lds,lei,les; int legal=0; lb=verb(mat,l,c,pecaac); lc=verc(mat,l,c,pecaac); le=hore(mat,l,c,pecaac); ld=hord(mat,l,c,pecaac); ldi=diadi(mat,l,c,pecaac); lds=diads(mat,l,c,pecaac); lei=diaei(mat,l,c,pecaac); les=diaes(mat,l,c,pecaac); legal = lb+lc+le+ld+ldi+lds+lei+les; printf("\n %d",legal); if (legal==0){ printf("Jogada ilegal"); } else{ return 1; } } int main(int argc, char *argv[]) { char matriz[7][7]; char pecaj, pecaai; int x,y; pecaj='X'; pecaai='O'; inimatri(matriz); showmat(matriz); x=6; y=4; clegal(matriz,x,y,pecaj); return 0; }
问题分析
你定义的是7行7列的数组char matriz[7][7],索引范围仅为0-6,但代码中所有循环和数组访问都在操作0-7的索引,直接触发了数组越界:
inimatri和showmat函数用l<8循环,会访问mat[7][...],超出数组的行边界- 多个检测函数(如
verb)中,当行索引为6时,l+1=7,会访问mat[7][c],越界访问栈内存 - Windows下未报错是因为内存布局和栈保护机制的差异,而Linux下GCC默认开启的栈保护机制会检测到非法内存修改,直接终止程序并提示"stack smashing detected"
解决方案
将数组定义和所有函数参数中的数组类型改为8x8,匹配代码中的8x8棋盘逻辑:
- 把
main函数里的char matriz[7][7];改为char matriz[8][8]; - 修改所有函数的参数,比如
void inimatri(char mat[7][7])改为void inimatri(char mat[8][8]),其他如showmat、hord等涉及二维数组的函数同理
修改后数组索引范围为0-7,与代码逻辑完全匹配,不会再出现越界访问,Linux下的栈保护机制也不会触发报错。
内容的提问来源于stack exchange,提问作者Tiago Jesus
相关产品推荐
相关产品推荐

