代码之家  ›  专栏  ›  技术社区  ›  Gleb Bespalov

为什么我在内存位置0x000000B70C8FF360处不断收到Microsoft C++异常:std::out_of_range。使用矢量时?

  •  -2
  • Gleb Bespalov  · 技术社区  · 1 年前

    Visual studio显示发现了0个问题,但当程序启动时,会弹出一个带有矢量库的选项卡,指向第2151行,并显示

    Unhandled exception at 0x00007FF90121CF19 in Project2.exe: Microsoft C++ exception: std::out_of_range at memory location
    

    我写了一个代码,用下一个矢量位置(k+1)检查矢量位置(k),如果它有相同的数字,它就会删除位置(k 当它达到向量的大小后,它应该停止检查和删除重复项,但我一直得到异常错误。我点击继续,它工作得很好,但每次“继续”后,它仍然显示一个异常错误。如何停止得到它?

    void removeDuplicates(vector<int>& nums) {
        int k = 0;
        while (k != nums.size() + 1) {
            vector<int>::iterator iter = nums.begin() + k;
            if (nums.at(k) == nums.at(k + 1)) {
                nums.erase(iter);
            }
            ++k;
        }
    }
    

    我试着点击继续,它工作得很好,但每次“继续”后都会显示一个异常错误。 在代码中,我试图删除“nums.begin()”旁边和“nums.at()”括号内的算术运算符,但无济于事。

    2 回复  |  直到 1 年前
        1
  •  1
  •   Chris    1 年前

    你肯定想检查一下 k < nums.size() 保持在范围内。你可以检查一下 k != nums.size() 但你的循环可以做一些聪明的事情,比如增量 k 1 然后跳过 nums.size() .

    但是你用索引 k + 1 ,所以你可能想要 k < nums.size() - 1 作为您的状况。您可能希望测试容器是否为空,如果是,请立即返回。

    我建议,除非绝对需要修改原始值,否则返回一个包含这些值的新向量。

        2
  •  0
  •   asmmo    1 年前

    您的代码仅尝试删除连续的重复项,因此函数名称不清楚。

    您使用索引的方式不对。索引从0开始,到结束 nums.size() -1 .

    检查这个 https://en.wikipedia.org/wiki/Erase%E2%80%93remove_idiom

    如果u在while循环之前定义k,那么它无疑是for循环

    工作代码示例。

    void removeSuccessiveDuplicates(std::vector<int>& nums) {
        size_t end = nums.size();
        for (size_t k = 0; k < end - 1; ++k) {
            if (nums[k] == nums[k + 1]) {
                for (size_t i=k+1;i<end-1;++i){std::swap(nums[i], nums[i+ 1]);}
                --end;
                --k; // Check the current index again in the next iteration
            }
        }
        nums.resize(end);
    }
    

    我本可以用 std::remove_if 具有 std::erase 或在当前示例中使用了rotate,但我只是想强调如何更正ur代码

    在这里玩 https://godbolt.org/z/j8f957T58

    推荐文章