【问题标题】:Garbage value of iterator value in C++C++中迭代器值的垃圾值
【发布时间】:2020-03-21 15:52:28
【问题描述】:

我正在解决一个问题,我需要在给定字符串中返回“1”的最后一个索引。如果不存在则返回-1。我写了下面的简单代码,但是对于输入字符串输入“0”它失败了。我尝试使用 GDB 调试 bu,我注意到一旦 index() 函数的循环语句运行一次,就会将垃圾值分配给迭代变量 i

#include <iostream>
#include <string>
using namespace std;

int index(string &str) {
    int result = -1;
    for(auto i = str.length() - 1; i >= 0; --i) {
        if(str[i] == '1')
            return i;
    }
    return result;
}
int main() {
    int T;
    cin >> T;
    cin.ignore();
    while(T--) {
        string str;
        cin >> str;
        cout << index(str) << endl;
    }
    return 0;
}

究竟是什么问题?

注意第二次迭代中i 的值。

【问题讨论】:

  • isize_t 类型,它是无符号的。它下溢。
  • @HolyBlackCat 这怎么可能? OP 一直在循环,直到它
  • @Chipste 不,他们一直在循环,直到它 i。
  • 你的截图真的很难看。您应该在此处发布时复制并粘贴您的 shell 会话的文本。

标签: c++ string


【解决方案1】:

您的程序在这里有未定义的行为:

for(auto i = str.length() - 1; i >= 0; --i) {
    if(str[i] == '1')
        return i;
}

The length() of an std::string has an unsigned type,并且由于您使用了auto,这意味着您的i 也未签名(准确地说,是std::size_t)。

这些值从不低于零。它们环绕到类型的最大值(一个非常大的数字!)。

所以,你的循环条件什么都不做;它总是正确的。相反,越界访问str[i] 然后发生,直到结果的未指定值之一恰好看起来像'1'。然后返回海量的i

可以通过标准容器或字符串向后循环,但you have to be careful about it。我给你的建议是使用迭代器;在这种情况下,reverse iterators

for (auto it = str.rcbegin(); it != str.rcend(); ++it)
{
    if (*it == '1')
        return std::distance(it, str.rcend());
}

【讨论】:

  • 我明白你的意思。但是对于使用i 会出现以下警告:从'unsigned long' 到有符号类型'int' 的缩小转换是实现定义的。有什么好的方法来解决这个问题?
  • @ArunSuryan 我添加了一些材料的链接供您阅读。花点时间研究一下。
猜你喜欢
  • 2012-09-15
  • 2013-05-07
  • 1970-01-01
  • 1970-01-01
  • 2013-03-19
  • 1970-01-01
  • 2016-01-26
  • 2017-10-28
  • 2022-06-14
相关资源
最近更新 更多