CLion中C++遍历vector程序异常退出(错误码-1073741819)排查
问题排查与修复方案
嘿,我来帮你搞定这个问题——你的程序崩溃(错误码-1073741819对应Windows下的STATUS_ACCESS_VIOLATION,也就是内存访问违规)主要是迭代器越界操作导致的,同时统计和排序逻辑也存在一些缺陷,咱们一步步拆解解决:
一、崩溃的直接原因
在stats函数的else块循环里,你写了这么一句判断:
else if (pair+1 == orderedCards.end()) orderedCards.push_back(std::make_pair(client[1], 1));
当pair指向orderedCards的最后一个元素时,pair+1会跑到尾后迭代器的下一个位置,这属于非法内存访问,直接触发了崩溃。迭代器的+1操作只有在pair不是最后一个元素时才安全,这个判断逻辑本身就有问题。
二、排序逻辑的小缺陷
你现在只对比了卡种字符串的第一个字符:
if (client[1][0] < pair->first[0])
这会导致错误的排序结果,比如如果有"amex"和"apple",首字母相同但后续字符不同,你的逻辑会错误处理它们的顺序。正确的做法应该是对比整个字符串的字典序(直接用client[1] < pair->first)。
三、更简洁高效的解决方案
其实完全不用手动维护有序vector并遍历统计,C++标准库的std::map刚好能满足你的需求——它本身就是按键的字典序排序的,统计+排序一步到位:
#include <iostream> #include <vector> #include <string> #include <map> void stats(const std::vector<std::vector<std::string>>& vec) { std::map<std::string, int> cardCount; // 统计每个卡种的数量 for (const auto& client : vec) { // 加个判断避免client元素不足导致越界 if (client.size() >= 2) { cardCount[client[1]]++; } } // 按字母顺序输出(map本身已经排好序了) for (const auto& entry : cardCount) { std::cout << entry.first << " " << entry.second << " "; } std::cout << std::endl; } std::vector<std::vector<std::string>> dataBase; int main() { dataBase = {{"name", "bankcard"},{"name", "visa"},{"name", "bankcard"},{"name", "mastercard"},{"name", "bankcard"},{"name", "visa"}}; stats(dataBase); return 0; }
运行这段代码,你会得到符合要求的输出:bankcard 3 mastercard 1 visa 2
四、如果你坚持用vector实现的修复方案
要是你想保留自己的vector+手动排序思路,我也给你修正了代码,解决了迭代器越界和排序问题:
#include <iostream> #include <vector> #include <string> #include <algorithm> // 用标准库算法简化逻辑 void stats(const std::vector<std::vector<std::string>>& vec) { std::vector<std::pair<std::string, int>> orderedCards; for (const auto& client : vec) { // 先查找是否已经存在该卡种 auto existingCard = std::find_if(orderedCards.begin(), orderedCards.end(), [&client](const std::pair<std::string, int>& p) { return p.first == client[1]; }); if (existingCard != orderedCards.end()) { // 存在就把计数加1 existingCard->second++; } else { // 不存在就找到正确的插入位置,保持字典序 auto insertPos = std::lower_bound(orderedCards.begin(), orderedCards.end(), std::make_pair(client[1], 0), [](const std::pair<std::string, int>& a, const std::pair<std::string, int>& b) { return a.first < b.first; }); orderedCards.insert(insertPos, std::make_pair(client[1], 1)); } } // 按要求用空格分隔输出 for (size_t i = 0; i < orderedCards.size(); ++i) { if (i != 0) std::cout << " "; std::cout << orderedCards[i].first << " " << orderedCards[i].second; } std::cout << std::endl; } std::vector<std::vector<std::string>> dataBase; int main() { dataBase = {{"name", "bankcard"},{"name", "visa"},{"name", "bankcard"},{"name", "mastercard"},{"name", "bankcard"},{"name", "visa"}}; stats(dataBase); return 0; }
修复点说明:
- 用
std::find_if替代手动遍历查找卡种,代码更简洁安全; - 用
std::lower_bound精准找到插入位置,确保vector始终按完整字符串的字典序排列; - 彻底避免了迭代器越界的问题;
- 输出格式改成了你要求的空格分隔形式。
内容的提问来源于stack exchange,提问作者xampierre
相关产品推荐
相关产品推荐

