当前位置: 首页 > 知识库问答 >
问题:

通过结束指针取消对数组类型的引用

韦智刚
2023-03-14

在C++中是否很好地定义了取消引用指向数组类型的一个结束指针?

请考虑以下代码:

#include <cassert>
#include <iterator>

int main()
{
    // An array of ints
    int my_array[] = { 1, 2, 3 };

    // Pointer to the array
    using array_ptr_t = int(*)[3];
    array_ptr_t my_array_ptr = &my_array;

    // Pointer one-past-the-end of the array
    array_ptr_t my_past_end = my_array_ptr + 1;

    // Is this valid?
    auto is_this_valid = *my_past_end;

    // Seems to yield one-past-the-end of my_array
    assert(is_this_valid == std::end(my_array));
}

通常的看法是,取消引用一个经过一个结束的指针是一种未定义的行为。但是,这对于指向数组类型的指针是否成立呢?

编辑:这个问题不是通过下标获取一个数组元素的地址的重复:根据C++标准是否合法?我在问问题中解释的规则是否也适用于指向数组类型的指针。

编辑2:删除auto以明确表示my_array_ptr不是int*

共有1个答案

彭飞虎
2023-03-14

这里是CWG232。这个问题看起来主要是关于取消引用空指针的问题,但从根本上讲,它是关于取消引用不指向对象的东西的意思。关于这个案例没有明确的语言规则。

其中一个例子是:

类似地,只要不使用值,就应该允许取消引用指向数组末尾的指针:

char a[10];
char *b = &a[10];   // equivalent to "char *b = &*(a+10);"

这与OP(上述表达式A[10]部分)基本相同,只是使用char而不是数组类型。

通常的看法是,取消引用一个经过一个结束的指针是一种未定义的行为。但是,这对于指向数组类型的指针是否成立呢?

基于是哪种指针的规则没有区别。my_past_end是一个pass-the-end指针,因此UB是否取消引用它并不取决于它指向一个数组,而不是任何其他类型。

 类似资料:
  • Go语言程序中对指针获取反射对象时,可以通过 reflect.Elem() 方法获取这个指针指向的元素类型。这个获取过程被称为取元素,等效于对指针类型变量做了一个 操作,代码如下: 代码输出如下: name: ''  kind: 'ptr' element name: 'cat', element kind: 'struct' 代码说明如下: 第 15 行,创建了cat结构体的实例,ins 是一个

  • 这是用C++语言编写的代码。 为什么在第一个cout语句中,程序尝试打印直到它找到一个空字符,而在第二个语句中,它只打印一个字符?

  • 本文向大家介绍C语言取消引用指针,包括了C语言取消引用指针的使用技巧和注意事项,需要的朋友参考一下 示例 要取消引用a_pointer并更改a的值,我们使用以下操作 可以使用以下打印语句对此进行验证。 但是,将一个NULL指针取消引用或其他无效指针将是错误的。这个 通常是未定义的行为。p1可能不会被取消引用,因为它指向的地址0xbad可能不是有效地址。谁知道那里有什么?它可能是操作系统内存,或另一

  • 嗨我有以下方法: 不得不提的是,startDate和endDate是长变量。我尝试在if条件中添加null检查,也尝试使用longValue()方法,但没有结果。你知道我怎样才能解决这个问题吗?可能是fndBugs端的bug?

  • 主要内容:关于数组指针的谜题数组(Array)是一系列具有相同类型的数据的集合,每一份数据叫做一个数组元素(Element)。数组中的所有元素在内存中是连续排列的,整个数组占用的是一块内存。以 为例,该数组在内存中的分布如下图所示: 定义数组时,要给出数组名和数组长度,数组名可以认为是一个 指针,它指向数组的第 0 个元素。 在C语言中,我们将第 0 个元素的地址称为数组的首地址。以上面的数组为例,下图是 arr 的指向: