取消引用 50% 的越界指针(数组数组) [英] Dereferencing a 50% out of bound pointer (array of array)

查看:34
本文介绍了取消引用 50% 的越界指针(数组数组)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的我不懂 C 和 C++ 中的指针"集合中的一个新问题.

This is a new question in my "I don't understand pointers in C and C++" collection.

如果我将具有相等值的两个指针的位(指向相同的内存地址)混合在一起,恰好具有完全相同的位表示,当一个是可取消引用的,一个是最后一个,标准怎么说应该发生吗?

If I mix the bits of two pointers with equal values (pointing to the same memory address), that happen to have exactly the same bit representation, when one is dereferenceable and one is one past the end, what does the standard say should happen?

#include <stdio.h>
#include <string.h>
#include <assert.h>

// required: a == b
// returns a copy of both a and b into dest 
// (half of the bytes of either pointers)
int *copy2to1 (int *a, int *b) {
    // check input: 
    // not only the pointers must be equal
    assert (a == b);
    // also the representation must match exactly
    int *dest;
    size_t s = sizeof(dest);
    assert(memcmp(&a, &b, s) == 0); 

    // copy a and b into dest:
    // on "exotic" architectures, size does't have to be dividable by 2
    size_t half = s/2; // = floor(s/2), 
    char *pa = (char*)&a, *pb = (char*)&b, *pd = (char*)&dest;

    // copy half of a into dest:
    memcpy (pd, pa, half);
    // copy half of b into dest:
    memcpy (pd+half, pb+half, s-half); // s-half = ceil(s/2)

    //printf ("a:%p b:%p dest:%p \n", a, b, dest);    

    // check result
    assert(memcmp(&dest, &a, s) == 0);
    assert(memcmp(&dest, &b, s) == 0);

    return dest;
}

#define S 1 // size of inner array

int main(void) {
    int a[2][S] = {{1},{2}};
    int *past = a[0] + S, // one past the end of inner array a[0]
        *val = &a[1][0], // valid dereferenceable pointer
        *mix = copy2to1 (past, val);
    #define PRINT(x) printf ("%s=%p, *%s=%d\n",#x,x,#x,*x)
    PRINT(past);
    PRINT(mix);
    PRINT(val);
    return 0;
}

我真正想明白的是:p指向对象x"是什么意思?

另见

这个问题是我之前关于数组数组的问题的更好版本:

This question is a better version of my previous questions about array of arrays:

  • Is memcpy of a pointer the same as assignment? which is a variation on my other question:
  • Dereferencing an out of bound pointer that contains the address of an object (array of array)

以及其他有关指针有效性的相关问题:

and other related questions about pointer validity:

推荐答案

在 [basic.compound] 中:

In [basic.compound]:

如果 T 类型的对象位于地址 A,则为 cv 类型的指针 T*> 其值为address A 被称为指向该对象,无论该值是如何获得的.

If an object of type T is located at an address A, a pointer of type cv T* whose value is the address A is said to point to that object, regardless of how the value was obtained.

pastval 具有相同的地址,因此它们指向相同的对象.一个是第一行的最后一个",第二个是第二行的第一个元素并不重要.在那个地址有一个有效的对象,所以这里的一切都是完全合理的.

past and val have the same address, so they point to the same object. It doesn't matter that one is "one past the end" of the first row and the second is the first element of the second row. There is a valid object at that address, so everything here is perfectly reasonable.

在 C++17 中,从 P0137 开始,这一点发生了很大变化.现在,[basic.compound] 将指针定义为:

In C++17, as of P0137, this changes a lot. Now, [basic.compound] defines pointers as:

指针类型的每个值都是以下之一:
— 一个指向对象或函数的指针(这个指针被称为指向对象或函数),或者
一个指针超过一个对象(5.7),或者
— 该类型的空指针值(4.11),或
无效的指针值.

Every value of pointer type is one of the following:
— a pointer to an object or function (the pointer is said to point to the object or function), or
a pointer past the end of an object (5.7), or
— the null pointer value (4.11) for that type, or
— an invalid pointer value.

所以现在,past 是第二种类型的值(一个指针的末尾),但是 val 是第一种类型的值(指向).这些是不同类别的值,没有可比性:

So now, past is a value of the 2nd type (a pointer past the end of), but val is a value of the 1st type (a pointer to). Those are different categories of values and are not comparable:

一个指针类型的值,即指向或越过对象末尾的指针,表示该对象所占用的内存(1.7)中的第一个字节的地址或所占用的存储末尾之后的内存中的第一个字节的地址分别由对象.[ 注意: 超过对象 (5.7) 末尾的指针不被认为指向可能位于该地址的对象类型的无关对象.指针值在它所表示的存储到达其存储期结束时失效;见 3.7.—结束注释]

A value of a pointer type that is a pointer to or past the end of an object represents the address of the first byte in memory (1.7) occupied by the object or the first byte in memory after the end of the storage occupied by the object, respectively. [ Note: A pointer past the end of an object (5.7) is not considered to point to an unrelated object of the object’s type that might be located at that address. A pointer value becomes invalid when the storage it denotes reaches the end of its storage duration; see 3.7. —end note ]

past 不指向某事,因此将其内容视为与 val 相同的内容不再有意义.

past doesn't point to something, so viewing its contents as if it were the same as val is no longer meaningful.

这篇关于取消引用 50% 的越界指针(数组数组)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆