C++数组相邻比较时最后一个元素的对比对象是什么?
问题原因分析
- 核心错误是循环边界设置错误:你的计数循环条件写的是
i < n,当循环执行到最后一次时,i = n - 1,此时访问s[i+1]等价于访问s[n],这已经超出了数组的合法下标范围(数组下标从0到n-1),属于缓冲区越界访问,是C++中的未定义行为。 - 额外补充:你代码中
std::string s[n];属于变长数组(VLA),这不是标准C++支持的语法,只是部分编译器(如GCC)提供的扩展特性,实际开发中建议替换为std::vector<std::string> s(n)避免兼容性问题和潜在的内存风险。
越界访问的内容说明
你的猜测完全正确,数组最后一个元素确实是和越界位置的值做比较:
数组s是在栈空间上分配的,
s[n]对应的是数组尾部之后紧邻的栈内存地址,这块内存的内容是未定义的,可能是之前栈操作留下的残留值、其他变量的值,完全没有确定规律。只是大多数场景下这块残留值对应的字符串内容不等于你数组最后一个元素的内容,所以会触发一次多余的自增,最终计数比预期多1。
修复方案
只需要把计数循环的条件从i < n修改为i < n - 1即可,修改后的循环逻辑只会对比到数组倒数第二个元素和最后一个元素,不会触发越界访问:
for (int i = 0; i < n - 1; i++) { if (s[i] != s[i+1]) { c++; } }
如果要完全符合C++标准,同时把数组定义替换为vector的完整代码如下:
#include <iostream> #include <vector> #include <string> int main() { int n, c = 0; std::cin >> n; std::vector<std::string> s(n); for (int i = 0; i < n; i++) { std::cin >> s[i]; } for (int i = 0; i < n - 1; i++) { if (s[i] != s[i+1]) { c++; } } std::cout << c; return 0; }
内容的提问来源于stack exchange,提问作者Muhamed Elsayed
相关产品推荐
相关产品推荐

