int m=44;
int* p= & m;
int* q = p-1
那么p是一个地址,我们如何从中减去1?q和*q 的输出是多少
此
int m=44;
在32位系统上如下图所示
0x103 0x102 0x101 0x100 (lets assume m base address is 0x100)
----------------------------------------------
| 0000 0000 | 0000 0000 | 0000 0000 |0010 1100 |
----------------------------------------------
m
MSB LSB
当你喜欢时
int *p = &m;
指针变量CCD_ 1指向CCD_
0x103 0x102 0x101 0x100
----------------------------------------------
| 0000 0000 | 0000 0000 | 0000 0000 |0010 1100 |
----------------------------------------------
m
|
p <-- points to 0x100
这个
int* q = p-1;
整数指针被分配了无效的p-1
,如下所示
0x107.................0x104 0x103 0x102 0x101 0x100
---------------------------------------------------------------------------
| un-initialized memory | 0000 0000 | 0000 0000 | 0000 0000 |0010 1100 |
---------------------------------------------------------------------------
<--q p
因此,如果您尝试执行*q
,它将尝试向前提取未为q
保留的数据0x104
,这将导致分段错误&导致未定义的行为。
好的,那么p是一个地址,我们如何从中减去1您可以执行q = p - 1
,因为这样做是将一个地址分配给它需要的q
,但重点是它不是有效地址,因此当您执行q
时,它崩溃了。例如
int main(void) {
int m=44;
int *p = &m;
int* q = p-1;
printf("%pn",(void*)q); /* this is valid */
//printf("%d n",*q); /* this cause seg fault */
return 0;
}
C++标准在[expr.add]/4:中对此进行了解释
将具有整型的表达式添加到指针或从指针中减去时,结果具有指针操作数的类型。如果表达式P指向具有n的数组对象x的元素x[i]元素,(…(表达式P-如果0≤i−J,J指向(可能是假设的(元素x[i−J]≤n否则,行为未定义。
因此,在您的情况下,行为是未定义的,因为p不指向数组。
在实践中,在大多数主流编译器上,q只会指向m之前的某个内存位置p
0字节。但由于该标准对内存布局没有太多说明,因此它可以位于任何位置。取消引用q可能会导致从垃圾值到segfault或内存损坏的任何奇怪行为
int m=44;
int*p=&m;
int*q=p-1
这里,q指向m之前的块,它是未初始化的。所以q会给出m-sizeof(int(的地址,*q会给你垃圾(值bw-(2^32(/2&(2^32(/2-1(。