C语言出现Stack smashing detected的原因分析:代码报错排查
栈溢出(Stack smashing detected)问题分析与修复
问题根源拆解
1. 字符串无终止符引发越界
C语言里的字符串操作函数(strcpy、strcmp、printf("%s"))全靠末尾的\0识别边界,但你的代码多处没处理这个关键细节:
char couples[length-1][2]:每个双字符组合只分配2字节空间,没预留\0的位置。用strcpy复制时,函数会持续读取内存直到找到\0,直接破坏栈空间结构。char mostCommonCouple[2]:同样只给2字节,存完两个字符后无法添加\0,printf输出时会越界读取内存。char element[]="":这个数组仅初始化1字节(仅包含\0),后续用strcpy复制双字符组合时,直接超出数组容量,触发栈溢出。
2. 字符串比较方式完全错误
if (couples[p]==tempElement)是在比较两个数组的内存地址,而非字符串内容。couples[p]和tempElement是栈上的不同数组,地址永远不相等,导致统计的出现次数全为0,逻辑彻底失效。正确做法是用strcmp比较字符串内容。
3. 字典序判断逻辑搞反
isLexicographicallyPreceding函数中,strcmp(couple1, couple2)>=0返回true,意思是couple1字典序更大或相等时算“靠前”,和实际要选字典序更小的需求完全相反。
修复后的代码
#include <stdio.h> #include <stdlib.h> #include <stdbool.h> #include <string.h> void printError(){ printf("Error: please check your input\n"); } // 判断couple1是否比couple2字典序更小 bool isLexicographicallySmaller(char couple1[], char couple2[]) { return strcmp(couple1, couple2) < 0; } void coupleDetector(int length, char word[], char result[]) { // 每个双字符组合需要3字节:2个字符 + 1个终止符 char couples[length-1][3]; for (int i=0; i<length-1; i++) { // 手动添加终止符,确保是合法字符串 couples[i][0] = word[i]; couples[i][1] = word[i+1]; couples[i][2] = '\0'; } // 初始化element为第一个组合,避免空数组问题 char element[3]; strcpy(element, couples[0]); int count = 1; for (int j=0; j<length-1; j++) { char tempElement[3]; strcpy(tempElement, couples[j]); int tempCount = 0; // 用strcmp比较字符串内容,而非地址 for (int p=0; p<length-1; p++) { if (strcmp(couples[p], tempElement) == 0) tempCount++; } if (tempCount > count) { strcpy(element, tempElement); count = tempCount; } // 计数相同时,替换为字典序更小的组合 else if (tempCount == count) { if (isLexicographicallySmaller(tempElement, element)) strcpy(element, tempElement); } } strcpy(result, element); } int main() { int length = 5; char arr[] = "ababa"; // 分配3字节空间存储双字符+终止符 char mostCommonCouple[3]; coupleDetector(length, arr, mostCommonCouple); printf("%s", mostCommonCouple); // 输出ba return 0; }
修复要点总结
- 所有存储双字符组合的数组改为3字节,手动添加
\0终止符,保证字符串操作安全。 - 将地址比较替换为
strcmp字符串内容比较,正确统计出现次数。 - 修正字典序判断逻辑,确保计数相同时选择字典序更小的组合。
- 初始化
element为第一个组合,避免空数组导致的未定义行为。
内容的提问来源于stack exchange,提问作者Blabla
相关产品推荐
相关产品推荐

