向量迭代器 + 偏移超出范围

Posted

技术标签:

【中文标题】向量迭代器 + 偏移超出范围【英文标题】:vector iterator + offset out of range 【发布时间】:2016-12-20 00:33:44 【问题描述】:

我是使用向量的新手,而且我对 C++ 的了解还很中级。我想创建一个函数来多次旋转数组并返回数组,这样我就可以拥有多个相同向量但旋转不同的数组。我这样做是为了在不改变数组初始值的情况下移动原始数组的位。现在我真的很挠头。 const 2d 数组故意很小,因为我知道大小与我的问题无关。

#include <algorithm>
#include <vector>
#include <iterator>

const int myconsts[1][8] =  
    1, 2, 3, 4, 5, 6, 7, 8
;

这是我的旋转功能

int *RotateAndErase(int rotNum) 
  int Shifted[8];
  int vectAdd = 0;
  std::vector<int> Shift;
  Shift.resize(sizeof(myconsts[0]));

  do 
    // Adds the constants to each vector
    Shift.push_back(myconsts[0][vectAdd]);
    vectAdd++;
   while (vectAdd < 8);
  // rotates desired direction(negative is right. positive is left)
  std::rotate(Shift.begin(), Shift.begin() + (rotNum), Shift.end());
  std::copy(Shift.begin(), Shift.end(), Shifted);
  return Shifted;
  Shift.erase(Shift.begin(), Shift.begin() + 8);
  delete Shifted;

在我的课堂上是怎么称呼的

class myclass 
 public:
  myclass() 
    int* Shift2 = RotateAndErase(2);
  

它是如何在 main 中调用的

int main() 
    myclass();
    return 0;

【问题讨论】:

为什么不const int myconsts[] = 1, 2, 3, 4, 5, 6, 7, 8;?您正在按字节数调整大小,而不是 myconsts[0] 中的元素数 您的代码中有一些严重的错误...超出范围是您现在最不担心的问题。例如,return Shifted 返回一个指向本地堆栈变量(错误)的指针,然后停止执行接下来的 2 行代码。 delete Shifted; 没有意义,因为您没有将Shifted 分配给new 抛开你的问题,问你几个问题:首先,你为什么要混合向量和数组?我看到的唯一原因是从一个转换到另一个,但除此之外......其次,您可能真的想阅读教程。为什么叫擦除?我可以假设您在 C 方面有一些经验,并且不习惯为您做所有繁琐的事情吗?最后一件事,为什么要使用大写的变量名?很不寻常。我的意思是,当然可以使用不寻常的编码风格,但我必须说,一开始我很困惑,乍一看并没有将 Shift 视为变量。 @Aziuth 我以前从未使用过向量。我来自 C 和 C# 背景,我才刚刚开始使用 C++。我最初以为我只需要使用向量来旋转数组,但我找到了一个更简单的解决方案。我通常只在函数中使用变量名 【参考方案1】:

这段代码有几个问题。导致错误的原因在这里:

std::vector<int> Shift;             # size is 0
Shift.resize(sizeof(myconsts[0]));  # size is 8*sizeof(int)

do 
Shift.push_back(myconsts[0][vectAdd]); # each push_back increases size by 1
vectAdd++;
 while (vectAdd < 8);
# size is now 8*sizeof(int) + 8
...
std::copy(Shift.begin(), Shift.end(), Shifted); # ouch! Shifted is int[8]

(您还返回了一个指向已失效局部变量的指针,但一次只返回一件事。)

编辑:正如 Ryan Haining 和 Mark Lakata 指出的那样,resize() 之后的大小我弄错了,它将是 8*sizeof(int),而不仅仅是 8。

【讨论】:

sizeof(myconsts[0]) 可能返回 32,即8*sizeof(int) 调整大小后将是8 * sizeof(int),而不是8 @MarkLakata:你是对的,我的错。但重点仍然是 >0。【参考方案2】:

这篇文章让我觉得很白痴。我在课堂上的其他函数看起来一点也不像这个。我发现我必须将Shift.resize() 更改为Shift.reserve()。我使用 std::cout 获取 sizeof shift、int 和我的数组的大小,然后将它们全部添加并放入 @987654324 @。此外,在摆弄代码后,旋转数不能高于向量中的元素数,它给了我同样的错误

这是我的精炼代码

std::vector<int> Rotate(int n, int arr[][8], int row) 
        int i = 0;
        std::vector<int> shift;
        //amount of bytes
        shift.reserve(sizeof(long) * 8);
        //amount of elements
        shift.resize(8);
        std::cout << "in: ";
        for (int i = 0; i < 8; i++) 
            std::cout << arr[row][i] << " ";
        
        std::cout << std::endl;
        do 
            shift[i] = arr[row][i];
            i++;
         while (i < 8);
        std::rotate(shift.begin(), shift.begin() + (n % 8), shift.end());

        std::cout << "out: ";
        for (int i = 0; i < 8; i++) 
            std::cout << shift[i] << " ";
        
        return shift;
    

【讨论】:

以上是关于向量迭代器 + 偏移超出范围的主要内容,如果未能解决你的问题,请参考以下文章

std::advance - 仅在调试时偏移超出范围失败

c++ 断言字符串迭代器偏移超出范围

“向量擦除迭代器超出范围”错误

矢量擦除迭代器超出范围[关闭]

c++和opencv中的向量下标超出范围错误

Kafka 消费者偏移超出范围,没有为分区配置重置策略