【问题标题】:What is the memory address of this pointer? [closed]这个指针的内存地址是什么? [关闭]
【发布时间】:2012-10-10 04:39:04
【问题描述】:

好的,所以在一次测试中我被问到了这个问题:

int* ptrA;    // assigned memory address 100
int a = 1;    // assigned memory address 600
ptrA = &a;

What is the memory address of ptrA + 2?

我以为是 606(int 是 4 个字节 + a 的地址,即 600 + 2 = 606,但显然答案是 608,我缺少什么才能做到这一点?

【问题讨论】:

  • 如果测试题的措辞是这样的,那么测试很糟糕。
  • 我非常怀疑这是否是测试中实际要求的内容......至少在某处会有PtrA = &a
  • @Jim:除非问题是故意检查学生是否注意到了这样的错误......
  • @TonyD 这很愚蠢,而且会使测试问题变得比现在更糟。请参阅 OP 的编辑。
  • 答案应该是 100 + (2*sizeof(int))。如果有no PtrA = &a声明,天知道608是从哪里来的

标签: c++ memory pointers int


【解决方案1】:

这是未定义的行为,表达式PtrA + 2 是非法的。您只能对您拥有的指针进行指针运算,并且不能添加或减去您拥有的数组范围之外的指针或超出范围的指针。

我们仍然可以分析这个(虽然没用,因为 UB)。你假设a 的地址是600 + 2,但不是,因为sizeof(int*) 可能也是4,所以它变成600 + 4。所以你得到600 + 4 + 4 = 608

【讨论】:

  • 我有点困惑 +2 是如何变成 +4 的。例如 - 如果问题是 ptrA + 10 会是 600+4+10 = 614?
  • @Howdy_McGee 这可能有点违反直觉,但是将 2 添加到 int* 会移动地址 两个整数,而不是 两个字节。因为 int 是 4 字节宽,所以实际上是在原始地址中添加了 8 个字节。
  • UB 之外,是否有任何实际架构中的指针算术无效指针不起作用? (当然,假设您从不取消引用无效指针)
  • 嘿@Howdy_McGee:对于您的查询,它将是 600 + (4)*10 = 640 。请参阅下面的评论.. 谢谢
  • @KirillKobelev RTFStandard ...你错了。只有超出对象末尾的元素 1 的地址才能被取...超出那个是 UB。
【解决方案2】:

实际上指针上的算术运算是不同的。它们的增加取决于数据类型的大小,所以如果给定一个地址说 x 并且你必须要求 x+ 2 ..(给定 x 是一个整数指针)然后 ..

x+ 2 表示 ---- x + (sizeof(int))*2

如果 x 是 char 指针,那么

x+2 表示 ---- x + (sizeof(char))*2

谢谢。

【讨论】:

  • 你是说它将是 sizeof(int*) 或 sizeof(char*)。这两个尺寸都是一样的。它是 sizeof(int) 或 sizeof(char)
  • @auny:是的,你是对的..现在编辑了..谢谢
  • 好答案.......................:)
【解决方案3】:

在 C 中,x + y 其中x 是一个指针,它等价于&x[y]。假设你有

int abc[3] = {1,2,3}; 
int* ptr = &abc[0];

&ptr[2](ptr + 2)是3的地址,明显比1的地址多了8个。

【讨论】:

  • "显然还有 8 个......" 不,直到你不说任何关于 sizeof(int) 的事情之前,它才会出现
  • @EmilioGaravaglia OP 写道“int 是 4 个字节”;其他答案,包括接受的答案,都是基于这种理解。
【解决方案4】:
int* PtrA;    // assigned memory address 100
int a = 1;    // assigned memory address 600

What is the memory address of ptrA + 2? 

这个问题模棱两可。

如果问题是“什么是(ptrA 的内存地址)+ 2?”,那么您已经说过 ptrA 位于内存地址 100(忽略 PtrA != ptrA),并将 2 添加到C 和 C++ 以指向类型大小的倍数递增,因此如果 int 为 32 位,则最终结果为 100 + 2 * 4 = 108。

如果问题是“(ptrA + 2) 的内存地址是什么?”,意思是 ptrA 变量和 2 中的值相加的结果,那么这是未定义的,因为没有显示 ptrA 的初始化并且尝试从未初始化的内存中读取是未定义的行为。

您的期望和假设的答案表明预期的代码...

ptrA = &a;

...在评估 ptrA + 2 之前的某个时间。如果这是真的,那么答案将是600 + 2 * sizeof(int),很可能是 608。

【讨论】:

  • +1 用于清楚地描述问题中的歧义,这揭示了测试作者的文盲。测试的目的应该是证明知识,而不是发出陷阱,询问不可能被理解的东西以欺骗错误的答案(特别是通过还原问题的含义,任何答案都可以是真假!)
【解决方案5】:

在 C/C++ 中,指针算法使用指针指向的对象的大小。例如:

int* PtrA = (int*)600;

PtrA+2 的值将是 608,前提是整数的大小为 4。

标准允许仅在数组内部或“在数组之后”进行指针运算。这意味着应该小心谨慎。

【讨论】:

    【解决方案6】:

    我认为,地址总是更多是不正确的。它也可以更少。可以肯定的是,说 ptr 是指向整数数组 a 的基地址的指针,那么 ptr+2 将指向数组的第三个元素。所以如果数组的基地址是600,那么地址可以是600+2*(sizeofIint)),也可以是600-2*sizeof(int);但无论如何,它将指向该数组的第三个元素。所以,我相信即使在数组的情况下,我们也不应该依赖直接地址。并且不应对 ptr+2 是否指向 608 或其他内容做出任何假设。

    感谢和问候, 索拉布

    【讨论】:

      猜你喜欢
      • 2021-01-03
      • 2016-02-08
      • 2021-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多