【问题标题】:c++ vector [-2] index returns weird value [duplicate]c ++向量[-2]索引返回奇怪的值[重复]
【发布时间】:2021-12-20 10:59:20
【问题描述】:

我是 C++ 新手,刚刚了解了向量。我来自 Python,所以当然我检查了是否可以在 c++ 中使用 负索引,这似乎不起作用。

在尝试检查它是否有效时,我在不同的环境中遇到了一个非常奇怪的负索引行为。

在.at() 函数中使用负索引会引发错误,但在使用[] 括号时不会。

这些值是以前内存位置的内容,还是它们代表什么?这就是所谓的undefined behaviour吗?

来源:

#include <iostream>
#include <vector>

int main() {
  std::vector<int> numbers = {3, 6, 9, 12, 15};
  std::cout << "Length: " << numbers.size() << "\n";
  for (int i = 4; i > -5; i--) {
    std::cout << "Pos " << i << ": " << numbers[i] << "\n";
  }
}

输出:

Length: 5
Pos 4: 15
Pos 3: 12
Pos 2: 9
Pos 1: 6
Pos 0: 3
Pos -1: 0   // other env: 201392090
Pos -2: 33  // other env: 475047512
Pos -3: 0
Pos -4: 0

【问题讨论】:

  • 是的,这就是所谓的未定义行为。
  • 如果您来自 Python,那么您最好习惯于需要从头开始学习一门新语言的想法。 Pythonic C++ 代码无法正常运行
  • 当您将某个数字pos 放在括号中作为vector 的索引时,它本质上表示vector.begin() + pos。这里,vector.begin() 是指向向量第一个元素的指针。如果您的 pos 为负数,那么它只会向您显示来自其他内存位置的数据。
  • 另外一个建议,python 索引和 c++ 索引是完全不同的。从零开始学习 c++,无需参考您的 Python 知识。而对于向量,最好使用迭代器而不是括号索引。

标签: c++


【解决方案1】:

这些值是以前内存位置的内容,还是它们代表什么?这就是所谓的未定义行为吗?

不,它实际上并不是在访问后备数组开头之前的内存位置,而是在末尾之后:

如果您使用numbers [index],编译器会将其解释为numbers.operator[](index),即使用member function operator[]()。这个函数接受一个size_t 类型的参数,它是一个无符号整数。参数-1 被隐式转换为无符号整数,产生一个非常大的数字,这个数字超出了std::vector 的合同涵盖的值范围。对此类元素的读或写访问是未定义的行为。 at 与 operator[]() 相比,确实将参数与向量大小进行比较,保证在这种情况下出现异常,但 operator[] 没有这样的“安全网”。

【讨论】:

    【解决方案2】:

    您可以在 C++ 中使用负索引,而不仅仅是在从索引 0 开始的容器上。

    但是,您可以将迭代器放入向量的中间并从中索引。

    std::vector<int> numbers = {3, 6, 9, 12, 15};
    std::vector<int>::iterator it = numbers.begin() + 3;
    std::cout << it[-2];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-06
      • 2019-08-06
      • 2019-05-29
      • 1970-01-01
      相关资源
      最近更新 更多