【问题标题】:Compilation error when trying to obtain a pointer to the size of a vector尝试获取指向向量大小的指针时出现编译错误
【发布时间】:2020-07-05 16:53:00
【问题描述】:

我有一个名为arrstd::vector<int> 实例,我想使用指针来处理它的长度。

我的声明

unsigned int *ptr = &arr.size();

给我一​​个编译错误:

cannot take the address of an rvalue of type 'size_type' (aka 'unsigned long').

即使我将指针的类型更改为size_t,此错误仍然存​​在。

这里有什么问题?

【问题讨论】:

  • arr.size() 返回size_t(即unsigned long long)。
  • 如果您不知道要放置什么数据类型,只需使用auto
  • 你不能取它的地址。是函数返回值。没有对象可以获取地址。只有指令可以创建一个对象(它是一个纯右值)。您可以将大小存储到一个变量中(实际上是创建一个对象)并获取它的地址,但是当向量的大小发生变化时这不会更新,并且对它的更改不会影响向量。
  • @RohanBari 在这种情况下,“size_t”是“unsigned long”,而不是“unsigned long long”。错误消息是这样说的。
  • 请比“使用它的长度”更具体。并阅读XY problem

标签: c++ pointers vector


【解决方案1】:

vector::size() 返回vector::size_type,通常为size_t 的无符号整数类型。但它按值返回,而不是按引用返回。所以size() 的结果是一个临时值,只会存在很短的时间。所以获取该返回值的地址是没有意义的,编译器禁止这样做。

vector 如何在内部存储大小取决于 STL,具体取决于实现。所以你不能得到指向vector 的大小成员的指针。事实上,这个变量甚至可能不存在。或者vector 可以在内部以字节为单位存储大小,而不是以元素为单位。

如果您想再次检查尺寸,请再次致电size()。您无法获得指向 vector 的大小变量的指针。

【讨论】:

    【解决方案2】:

    在这段代码中:

    std::vector<int> arr;
    unsigned int* ptr = &(arr.size());
    

    arr.size() 的结果将是一些临时值,例如42。不管ptr的类型是否正确,根本不允许你取临时地址。

    如果你想要一个迭代器到 vector 的末尾,你可以这样做:

    auto i = arr.end();
    

    如果你真的想要一个指向vector 结尾的指针,你可以这样做:

    int * p = arr.data() + arr.size();
    

    【讨论】:

    • 我肯定会not recommend 索引越界并获取地址。即使编译器最终为常规数组提供了一些余地,因为 C 需要它工作,但将其与标准容器一起使用是另一回事。
    • @chris 是的,这很愚蠢。不知道我在想什么:p 感谢您发现这一点。并努力做一个清晰的演示:)
    • 插入或删除元素后会怎样?!
    • @asmmo 然后迭代器/指针将失效。你问的是这个吗?
    • @cigien 不,我是说使用这个迭代器/ptr 是个坏主意,因为我提到的原因
    【解决方案3】:

    无法获取arr.size()的指针,因为该方法返回右值(就像获取数字10的地址一样)。更改矢量大小的唯一方法是添加或删除其中的元素。

    【讨论】:

      【解决方案4】:

      看起来你是 C++ 的初学者。您面临的问题非常普遍,因此您必须了解问题所在。基本上 arr.size() 返回一个类型为 size_t 的变量。那不重要。重要的是如何返回这个值。是这样的:

      size_t size() { return size; }

      因此,您返回一个值,并且您想查看它存储在哪里。它不存储在内存中,因为它是按值返回的。按值返回什么?

      这意味着您创建原始变量(在我们的示例中为大小)的副本,然后返回该副本。然而,这个副本没有存储在任何地方(它是,但这是高级的东西,因为它涉及寄存器)。未存储在任何地方的变量没有内存位置,因此您无法获取指向该变量的指针。

      我希望这可以清除它,但如果您有任何问题,请提出。如果您有兴趣,您可能还想搜索诸如按值传递、按引用传递、指针、C++ 中的引用等内容,但它可能会给您提供太多信息,您会不知所措。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-09-03
        • 2013-04-14
        相关资源
        最近更新 更多