【问题标题】:Terminate called after throwing an instance of 'std::out_of_range' error while using vector在使用向量时抛出“std::out_of_range”错误实例后调用终止
【发布时间】:2021-01-21 06:26:09
【问题描述】:
#include<iostream>
#include<vector>
using namespace std;
int count=0;
int checkDivisor(int d,int*ptr){
    vector<int> v;
    int temp=0;
for (int i = *ptr; ; i++)
{
   for (int j = 1; j<=i; j++)
   {
       if(i%j==0){
           v.push_back(j);
           count++;
       }
   }
   if (count>=4)
   {
       temp=i;
      break;
   }
   else
   {
       v.clear();
   }
}
for(int k=0;k<v.size();k++){
    if ((v.at(k+1)-v.at(k))<=d)
    {
       return 0;
    }
}
return temp;
}

int main(){
int t;
cin>>t;
while (t>0)
{   
    int d;
    cin>>d;
    int value=0;
    int*point=&value;
    int result=checkDivisor(d,point);
    if(result==0){
        *point++;
        checkDivisor(d,point);
    }
    else{
    cout<<checkDivisor(d,point)<<endl;
    }
    t--;
}
return 0;
}

这会在抛出 'std::out_of_range' 的实例后返回一个错误终止调用 what(): vector::_M_range_check: __n (即 1) >= this->size() (即 1)。 我要做的是返回一个数字,如果它有超过 3 个除数并且任何两个除数之间的差大于 d 请帮忙。

【问题讨论】:

  • k 上升到 size -1 并且您正在尝试访问超出向量范围的 k+1

标签: c++ vector error-handling runtime-error outofrangeexception


【解决方案1】:

此代码if ((v.at(k+1)-v.at(k))&lt;=d) 获取索引k+1 处的数字。但是当k 等于v.size()-1 k+1 等于v.size() 时,这是一个超出范围的错误。

现在已经指出了这一点,我相信这对你来说是显而易见的。您应该培养查看自己的代码并理解其作用的能力,尤其是当错误消息准确地告诉您您做错了什么时。

大概是这段代码

for(int k=0;k<v.size();k++){

应该是这样的

for(int k=0;k<v.size()-1;k++){

【讨论】:

    【解决方案2】:

    std::vector::at 进行范围检查。错误发生在您的for (k=0; k &lt; v.size(); ++k) 循环中,您尝试访问v.at(k+1)。当k=v.size()-1 时,这是超出范围的。另外,你有什么理由将ptr 作为指针传递?我建议按价值传递。你的逻辑也有几个问题。这是一个有效的示例(对于正数数字):

    #include<iostream>
    #include<vector>
    #include<limits>
    std::vector<int> try_get_first_n_divisors(const int number, const int n)
    {
        std::vector<int> v;
        for (int divisor = 1; divisor <= number; divisor++)
        {
            // check if it is a divisor of number
            if(number%divisor==0)
            {
                // is so, add it to the vector
                v.push_back(divisor);
    
                // When we found more than four divisors, leave the loop
                if(v.size() == 4)
                    break;
            }  
        }
        return v;
    }
    
    bool check_divisor_dist_cirterion(int d, int number){
    
        std::vector<int> v = try_get_first_n_divisors(number, 4);
        
        if (v.size() < 4)
            return false;
        else
        {
            // check the distance between divisors
            for(int k=1; k<v.size(); ++k){
                if ((v.at(k)-v.at(k-1)) <= d)
                {
                    return false;
                }
            }
        }
        return true;
    }
    
    int main(){ 
    
        int d;
        std::cin>>d;
        int number = 4;
        while(!check_divisor_dist_cirterion(d, number) 
            && (number < std::numeric_limits<int>::max()))
        {
            ++number;
        }
        
        std::cout << "found " << number << " with divisors ";
        for (auto divisor : try_get_first_n_divisors(number, 4))
            std::cout << "  " << divisor;
        std::cout << std::endl;
    
        return 0;
    }
    

    live demo

    请注意,您传递给检查标准的数字也是一个除数。如果你想改变这一点,那么你必须在 try_get_first_n_divisors中使用&lt;比较:for (int divisor = 1; divisor &lt; number; divisor++)

    此外,此示例未优化。例如,如果距离 > 1,那么您可以跳过偶数,因为 1, 2 将始终是除数,因此违反了您的标准。

    注意我没有检查负数的逻辑。

    【讨论】:

      猜你喜欢
      • 2021-01-02
      • 2017-03-08
      • 1970-01-01
      • 1970-01-01
      • 2021-06-04
      • 2014-05-24
      相关资源
      最近更新 更多