这是我的“我不明白 C 和 C++ 中的指针”集合中的一个新问题。
如果我将两个具有相同值的指针的位(指向相同的内存地址)混合在一起,那么它们恰好具有完全相同的位表示形式,当一个是可解引用的并且一个是超出末尾的一个时,标准是怎么说的应该发生吗?
#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”是什么意思?
另请参阅
这个问题是我之前关于数组数组的问题的更好版本:
- Is memcpy of a pointer the same as assignment?这是我的另一个问题的变体:
- Dereferencing an out of bound pointer that contains the address of an object (array of array)
以及其他有关指针有效性的相关问题:
最佳答案
在[基本.化合物]中:
If an object of type
T
is located at an addressA
, a pointer of type cvT*
whose value is the addressA
is said to point to that object, regardless of how the value was obtained.
past
和 val
有相同的地址,因此它们指向同一个对象。一个是第一行的“最后一个元素”,第二个是第二行的第一个元素,这并不重要。该地址有一个有效的对象,因此这里的一切都是完全合理的。
在 C++17 中,自 P0137 起,这变化很大。现在,[basic.compound] 将指针定义为:
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
是第一种类型的值(指向)。这些是不同类别的值,不具有可比性:
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
相同的内容不再有意义。
关于c++ - 取消引用 50% 出界指针(数组的数组),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32100245/