【问题标题】:Pointer of int type moves 1 address in memory after incrementing itint 类型的指针在递增后移动内存中的 1 个地址
【发布时间】:2015-05-24 23:51:18
【问题描述】:

代码按预期工作,直到第 22-24 行,我们打印 8 后跟地址。增加指针地址只会将地址增加一个字节,而它应该将地址移动 4 个字节。数组中或单独运行第 22-24 行时不会出现此问题。

#include<iostream>
using namespace std;

void main()
{
   int *p;
   //int a[10] = { 0 };
   //p = a;
   int a = 100;
   p=&a;
   cout << "1.    "<<p <<"    "<<*p<< endl;
   p++;
   cout << "2.    " << p << "    " << *p << endl;
   ++p;
   cout << "3.    " << p << "    " << *p << endl;
   ++*p;
   cout << "4.    " << p << "    " << *p << endl;
   ++(*p);
   cout << "5.    " << p << "    " << *p << endl;
   ++*(p);
   cout << "6.    " << p << "    " << *p << endl;
   *p++;
   cout << "7.    " << p << "    " << *p << endl;
   (*p)++;      //This is the problem, increments the address by 1,    even though its in int type
   cout << "8.    " << p << "    " << *p << endl;
   *(p)++;
   cout << "9.    " << p << "    " << *p << endl;
   *++p;
   cout << "10.    " << p << "    " << *p << endl;
   *(++p);
   cout << "11.    " << p << "    " << *p << endl;
   cin.get();
}

【问题讨论】:

  • 在此声明中 (*p)++;地址本身不会增加。后递增的是 *p 的值。
  • @VladfromMoscow 不幸的是,我无法在此处发布输出的屏幕截图,但地址正在递增 1。地址从 00C1FA14 变为 00C1FA15。
  • 在任何情况下程序都有未定义的行为。
  • 你在“cout

标签: c++ pointers increment


【解决方案1】:

你的代码是:

p = &a;
p++;

现在p 指向a 的末尾。这仍然可以,但是在下一行:

cout << "2.    " << p << "    " << *p << endl;

当您写入*p 时,它会尝试读取a 末尾之后的内存,从而导致undefined behaviour

当未定义的行为发生时,C++ 语言的定义不再涵盖程序所做的事情。任何事情都有可能发生。

换句话说:在生成可执行文件时,编译器可以基于您的程序只执行定义明确的事情的前提做出假设。

您的输出也许可以通过编译器做出这样的假设来解释,如果您的程序正在确认,这将是合理的,但实际上是错误的,因为您的程序无效。

想到的一种解释是,您将p 前进,直到它恰好指向存储p 本身的内存位置。编译器通过输出用于递增存储在p 指向的位置的int 的指令来实现(*p)++。在您的系统上,将此指令应用于实际存储p 的位置的结果是将p 的地址值增加一。

【讨论】:

  • 尝试修复您的程序,使其永远不会读取或写入无效内存(并且没有任何其他 UB 实例),您应该会发现奇怪的输出消失了。 (如果没有,请发布您正在运行的代码以及实际输出的复制粘贴)。
【解决方案2】:

最初,您将 p 设置为指向堆栈上的整数变量。当您随后增加指针时,您将指向堆栈上的内存区域,该区域可能会在调用函数时发生变化(例如 cout )。当函数返回时,它可能会更改递增指针 p 指向的内存位置,这可能解释了您的问题。 您应该声明一个足够大的数组,以容纳您将要单步执行的指针地址范围。我注意到您注释掉了可以按预期工作的数组代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-10-29
    • 1970-01-01
    • 2012-10-23
    • 2013-12-22
    • 1970-01-01
    • 2020-12-03
    • 1970-01-01
    • 2012-10-19
    相关资源
    最近更新 更多