程序触发EXC_BAD_ACCESS错误且排序不符预期,求原因及修复方案
问题分析与修复方案
问题成因拆解
1. 输出顺序颠倒
你的代码意图是按字典序升序输出账号信息,但当前结果完全反转,核心原因有两个:
- 栈是**后进先出(LIFO)**结构:你最后从栈顶依次
pop()元素输出,这会让最后压入栈的元素最先被打印; - 排序逻辑错误:当
alpha_Compare返回best(比如Reddit)时,你执行了弹出原栈顶、压入新字符串再压回原栈顶的操作,导致栈中Facebook在底层,Reddit在栈顶,最终输出顺序颠倒。
2. EXC_BAD_ACCESS 崩溃错误
这个内存访问错误是因为访问了空栈的top()或执行pop(),根源在于:
loops变量的计算和栈的实际元素数量不一致:你通过loops++记录输出数量,但遇到空元素break时,loops已经被提前递增;- 排序分支的栈操作改变了元素数量:在
if (tipTop == best)分支中,你pop()1次、push()2次,栈元素数量会额外增加1,但loops只加1,最终循环取元素时会超出栈的实际大小,触发未定义行为。
修复方案
方案1:修正栈排序逻辑(保留栈实现)
调整排序逻辑,同时避免依赖loops变量,直接用栈的empty()控制循环:
void alpha_Array(){ std::string nameArr[50]; nameArr[0] = "Reddit"; nameArr[1] = "Facebook"; std::string passArr[50]; passArr[0] = "1"; passArr[1] = "2"; std::stack<std::string> organiser; std::stack<std::string> passwordStack; // 初始化栈 organiser.push(nameArr[0]); passwordStack.push(passArr[0]); for(int x = 1; x < 50; x++){ if (nameArr[x].empty()) break; std::string currName = nameArr[x]; std::string currPass = passArr[x]; std::stack<std::string> tempName; std::stack<std::string> tempPass; // 将栈中比当前元素大的元素暂存到临时栈 while(!organiser.empty() && alpha_Compare(organiser.top(), currName, 0) == organiser.top()){ tempName.push(organiser.top()); tempPass.push(passwordStack.top()); organiser.pop(); passwordStack.pop(); } // 压入当前元素 organiser.push(currName); passwordStack.push(currPass); // 把临时栈元素压回原栈 while(!tempName.empty()){ organiser.push(tempName.top()); passwordStack.push(tempPass.top()); tempName.pop(); tempPass.pop(); } } // 反转栈得到升序输出 std::stack<std::string> revName; std::stack<std::string> revPass; while(!organiser.empty()){ revName.push(organiser.top()); revPass.push(passwordStack.top()); organiser.pop(); passwordStack.pop(); } // 输出结果 while(!revName.empty()){ std::cout<<"Name: "<<revName.top()<<std::endl <<"Password: "<<revPass.top()<<std::endl<<std::endl; revName.pop(); revPass.pop(); } }
方案2:用更简洁的容器替代栈(推荐)
栈并不适合排序场景,推荐用std::vector存储数据,配合std::sort实现排序,代码更易维护:
#include <algorithm> // 必须包含此头文件 void alpha_Array(){ // 用结构体绑定名称和密码,避免排序时数据错位 struct Account { std::string name; std::string password; }; Account accounts[50] = {{"Reddit", "1"}, {"Facebook", "2"}}; std::vector<Account> accountList; // 加载有效数据到vector for(int x = 0; x < 50; x++){ if (accounts[x].name.empty()) break; accountList.push_back(accounts[x]); } // 按名称字典序升序排序 std::sort(accountList.begin(), accountList.end(), [](const Account& a, const Account& b){ return a.name < b.name; // 利用string默认字典序比较 }); // 输出结果 for(const auto& acc : accountList){ std::cout<<"Name: "<<acc.name<<std::endl <<"Password: "<<acc.password<<std::endl<<std::endl; } }
关键注意事项
- 确保
alpha_Compare函数逻辑正确:如果它的作用是返回字典序更小的字符串,内部应返回a < b ? a : b; - 永远不要直接依赖计数变量控制栈的操作,优先使用
empty()或size()判断栈的状态,避免空栈访问。
内容的提问来源于stack exchange,提问作者Qwong
相关产品推荐
相关产品推荐

