【问题标题】:Can a char vector go out of bounds?char 向量可以越界吗?
【发布时间】:2020-04-25 19:17:24
【问题描述】:

我只是逐个字符地读取数字字符串,直到输入“\n”。

vector <char> pay;
vector <char> :: iterator p;
char x;
char maxdigit;
if(flag==1)
{
    cin.ignore();       // to ignore the first enter key press, after the test case         
    flag=0;
}

for(long long int i=0; ; i++)
{
    cin.get(x);     // The >> operator doesn't detect the ENTER key, so the loop won't end
    if(x=='\n') 
        break;
    pay.push_back(x);
}

找到最大位数或最佳位数以删除以最小化输入的数字。

if(pay[1]=='0')
{
    pay.erase(pay.begin());
    while(pay[0]=='0')
        pay.erase(pay.begin());
}
else
{
    maxdigit=*max_element(pay.begin(),pay.end());
    p = find(pay.begin(),pay.end(),maxdigit);
    pay.erase(p);   
}

但我收到一个 sigsegv 错误,如有任何帮助,我们将不胜感激。

【问题讨论】:

  • 如果用户在没有输入任何数字的情况下直接按回车,向量将为空,if(pay[1]=='0') 将超出范围。
  • 为了测试,您可以将所有[] 替换为at(),这将执行边界检查并帮助您缩小错误位置。
  • 第一部分可以替换为std::getline
  • 你用过调试器吗?这应该会很快将您指出错误。

标签: c++ vector stl segmentation-fault


【解决方案1】:

是的,您的代码中有很多地方会导致段错误(或其他未定义的行为):

if(pay[1]=='0') // UB if pay.size() < 2
{
    pay.erase(pay.begin());
    while(pay[0]=='0') // UB if pay.size() < 1, e.g. if pay is originally "00000" this loop has UB
        pay.erase(pay.begin()); // UB if pay.size() < 1
}
else
{
    maxdigit=*max_element(pay.begin(),pay.end()); // UB if pay is empty, max_element will return pay.end(), dereferencing this iterator is UB
    p = find(pay.begin(),pay.end(),maxdigit);
    pay.erase(p);   
}

更安全的代码是:

if(!pay.empty() && pay.front()=='0') // I'm assuming pay[1]=='0' was meant to be pay[0]=='0'
{
    pay.erase(pay.begin());
    while(!pay.empty() && pay.front()=='0')
        pay.erase(pay.begin());
}
else
{
    p = max_element(pay.begin(),pay.end());
    if (p != pay.end())
    {
        maxdigit = *p;
        pay.erase(p);
    } 
}

【讨论】:

  • 假设 pay[1]=='0' 不正确。虽然我确实忘记检查向量是否为空。另外我不明白 if (p != pay.end()) 条件,我必须删除一个元素,即使它位于向量的末尾。
  • pay.end() 不是向量中的最后一个元素,它是向量中最后一个元素之后的元素,在pay.end() 上调用*p 是未定义的行为,pay.erase(pay.end()) 也是不明确的。查看第一块代码中的 cmets
猜你喜欢
  • 2014-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-02-27
  • 2023-03-03
  • 2011-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多