cur*_*guy -2 c c++ arrays pointers language-lawyer
这是我在"我不理解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;
}
Run Code Online (Sandbox Code Playgroud)
我真正想要理解的是:"p指向对象x"是什么意思?
也可以看看
这个问题是我之前关于数组数组问题的更好的版本:
和指针有效性的其他相关问题:
在[basic.compound]中:
如果类型的对象
T位于地址A,则表示值为地址的类型为cvT*的指针A将指向该对象,而不管该值是如何获得的.
past并且val具有相同的地址,因此它们指向同一个对象.一个是"第一行的一个结束"并且第二个是第二行的第一个元素并不重要.该地址有一个有效的对象,所以这里的一切都是完全合理的.
在C++ 17中,从P0137开始,这种情况发生了很大的变化.现在,[basic.compound]将指针定义为:
指针类型的每个值是下列之一:
-一个指针的对象或函数(指针被说成指向的对象或功能),或
- 一个指针过去的端部的对象(5.7),或
-所述该类型的空指针值(4.11),或
- 无效的指针值.
所以现在,past是第二种类型的值(超过结尾的指针),但是val第一种类型的值(指向).这些是不同类别的价值观,不具有可比性:
指针类型的值是指向或超过对象末尾的指针,表示对象占用的内存中的第一个字节的地址(1.7)或者在对象占用的存储结束后内存中的第一个字节的地址, 分别.[注意:超过对象末尾的指针(5.7)不被视为指向可能位于该地址的对象类型的无关对象.当指示的存储达到其存储持续时间的末尾时,指针值变为无效; 见3.7. - 尾注]
past没有指向什么,所以查看它的内容就好像它是相同的val不再有意义.
| 归档时间: |
|
| 查看次数: |
1272 次 |
| 最近记录: |