C++中set显示size为1却无法打印元素的问题排查
问题分析与解决:std::set size显示1但遍历无输出的原因
核心问题:字符串下标越界访问
你的代码中存在未定义行为:外层循环i <= s.length()、内层循环j <= s.length(),当j等于s.length()时,s[j]访问的是超出std::string有效范围的内存位置。C++字符串的有效下标范围是0到s.length()-1,访问s.length()会读取未知内存值,大概率是'\0'(空字符)。
为什么size为1但遍历无输出
std::set<char>会将这个空字符存入集合,因此mems.size()返回1。- 空字符是不可打印字符,用
cout输出时不会在控制台显示任何内容,所以遍历看起来没有元素输出,但集合内确实存在一个空字符元素。
为什么预期size为2未达成
原逻辑想要插入字符串的两个字符'a'和'u',但越界访问插入的空字符打乱了正常流程,同时内层循环中直接修改外层循环变量i的操作,也干扰了循环的正常迭代,导致集合无法按预期存储两个有效字符。
修复方案
- 修正循环条件,避免越界:将
i <= s.length()改为i < s.length(),j <= s.length()改为j < s.length()。 - 优化逻辑:原嵌套循环的写法容易出错,改用滑动窗口实现最长无重复子串的逻辑更清晰可靠。
修正后的示例代码:
#include <algorithm> #include <iostream> #include <set> using namespace std; int main() { string s = "au"; std::set<char> mems; int ans = 0; int left = 0; // 滑动窗口实现最长无重复子串 for (int right = 0; right < s.length(); ++right) { // 若当前字符已存在,移除左边界字符直到无重复 while (mems.count(s[right])) { mems.erase(s[left]); left++; } mems.insert(s[right]); ans = max(ans, right - left + 1); } cout << "最长无重复子串长度:" << ans << endl; cout << "集合元素:"; for (auto item : mems) { cout << item << " "; } cout << endl; cout << "集合大小:" << mems.size() << endl; return 0; }
内容的提问来源于stack exchange,提问作者Brian
相关产品推荐
相关产品推荐

