C++奇怪的指针运算



当我在C++中摆弄指针时,我遇到了一个奇怪的输出。不太确定这是否会在其他编译器上提供相同的输出,但我尝试过GCC 5.1.0、4.8.1,结果是相同的。

int main(){
   int a = 10;
   int b = 40;
   int *ptrA = &a;
   cout<<*(ptrA-1);
   int *ptrB = &b;
   return 0;
}

我在这段代码中所做的是尝试访问堆栈框架中声明的下一个变量。由于堆栈从虚拟内存的顶部增长到底部,因此我从ptrA中减去1,以便将其指向存储b的下一个4位。在这种情况下,输出为40。

当我移除线路时发生"异常"

int *ptrB = &b;

在这种情况下,相同的代码输出65(其他编译器给我的输出与GCC不同,但删除这一行后,输出再次与初始代码不同)。现在出现了两个问题。

  1. cout<<*(ptrA-1);之后的简单指针初始化语句如何以这种方式影响程序
  2. 为什么在不写入行int *ptrB = &b;的情况下,程序不打印b的值

您正在调用udefined行为。在这种情况下,这是如何表现出来的,可以通过查看从代码示例生成的汇编代码来确定(为此,请使用-S选项调用g++。)但一种可能性是,当您不获取b的地址时,优化器会优化该变量。

您不应对堆栈布局做出任何假设。你所做的是不明确的行为,充满了惊喜。

添加额外的本地指针变量的定义会影响堆栈的布局。编译器可以在声明时执行,也可以在准备函数的堆栈帧时预留一些空间。这解释了附加行如何影响结果。当然,这完全取决于实现。

该标准仅在同一对象/数组中定义指针算法:

5.7/4:对于这些运算符[,即加法/减法],指向非数组对象的指针的行为与指向长度为1的数组,其元素为对象的类型类型

5.7/5:(…)如果表达式p指向数组对象的第i个元素,则表达式(p)+N和(P)-N(其中N的值为N)分别指向阵列的第i+N个和第i−N个元素对象,,前提是它们存在。(…)如果指针操作数和结果都指向相同的数组对象或数组对象的最后一个元素之后的一个,评估不得产生溢出;否则,行为未定义。

您可能还对这个关于使用不同编译选项更改堆栈布局的响应感兴趣。

相关内容

  • 没有找到相关文章

最新更新